Saya melihat bahwa g
akan berpindah dari konteks permintaan ke konteks aplikasi di Flask 0.10, yang membuat saya bingung tentang tujuan penggunaan g
.
Pemahaman saya (untuk Flask 0.9) adalah bahwa:
g
tinggal dalam konteks permintaan, yaitu, dibuat baru ketika permintaan dimulai, dan tersedia hingga berakhirg
dimaksudkan untuk digunakan sebagai "papan tulis permintaan", di mana saya dapat menaruh barang-barang yang relevan selama durasi permintaan (yaitu, menetapkan bendera di awal permintaan dan menanganinya di akhir, mungkin dari abefore_request
/after_request
pair)- selain memegang status tingkat permintaan,
g
dapat dan harus digunakan untuk manajemen sumber daya, yaitu, memegang koneksi basis data, dll.
Manakah dari kalimat-kalimat ini yang tidak lagi benar dalam Flask 0.10? Bisakah seseorang mengarahkan saya ke sumber yang membahas alasan perubahan itu? Apa yang harus saya gunakan sebagai "papan tulis permintaan" di Flask 0.10 - haruskah saya membuat aplikasi sendiri / proxy lokal thread-ekstensi spesifik saya dan mendorongnya ke tumpukan konteks before_request
? Apa gunanya manajemen sumber daya pada konteks aplikasi, jika aplikasi saya hidup untuk waktu yang lama (tidak seperti permintaan) dan dengan demikian sumber daya tidak pernah dibebaskan?
g
di 0,10, kalau tidak sepertinya banyak kode mungkin mulai mengembangkan beberapa bug yang licik.flask.g
. speakerdeck.com/mitsuhiko/advanced-flask-patterns-1Jawaban:
Pola Labu Lanjutan , seperti yang ditautkan oleh Markus , menjelaskan beberapa perubahan
g
pada 0.10:g
sekarang tinggal dalam konteks aplikasi.g
masih dapat digunakan untuk mengatur flag per-request tanpa mengubah kode.teardown_request
dipanggil. (Presentasi Armin menjelaskan ini karena hal-hal seperti membuat koneksi DB adalah tugas yang mengatur lingkungan untuk permintaan, dan tidak boleh ditangani di dalambefore_request
danafter_request
)sumber
app_ctx is None or app_ctx.app != self.app
False, konteks aplikasi lama tampaknya digunakan kembali? Ini sepertinya tidak benar, karena konteks aplikasi "tidak akan dibagikan di antara permintaan" ...app.app_context()
? Jika demikian, harus dicatatapp_context()
instantiates konteks aplikasi baru setiap panggilan - itu tidak pernah menggunakan kembali konteks.app_ctx is not None and app_ctx.app == self.app
,app_ctx = self.app.app_context()
garis tidak dieksekusi; hanyaself._implicit_app_ctx_stack.append(None)
dieksekusi dalam kasus ini.RequestContext
yang didorong, jadi hanya satuAppContext
yang didorong. Tetapi jika mode debug aktif dan permintaan gagal, Flask menyimpan konteksnya , sehingga dapat digunakan dengan debugger .None
ditambahkan ke_app_ctx_stack
, jadi ketika permintaan sedang dirobohkan, ia tahu belum munculAppContext
dulu. Hal yang sama terjadi dengan klien uji, yang mempertahankan konteksnya, sehingga dapat diperiksa.Sebagai tambahan pada informasi di utas ini: Saya agak bingung dengan perilaku
flask.g
juga, tetapi beberapa pengujian cepat telah membantu saya untuk mengklarifikasi hal itu. Inilah yang saya coba:Dan inilah output yang diberikannya:
Seperti kata Y4Kman di atas, "Setiap permintaan mendorong konteks aplikasi baru". Dan seperti yang dikatakan oleh Flask , konteks aplikasi "tidak akan dibagikan di antara permintaan". Sekarang, apa yang belum dinyatakan secara eksplisit (meskipun saya kira itu tersirat dari pernyataan ini), dan apa yang ditunjukkan oleh pengujian saya, adalah bahwa Anda tidak boleh secara eksplisit membuat beberapa konteks permintaan yang bersarang di dalam satu konteks aplikasi, karena
flask.g
(dan co) tidak tidak memiliki keajaiban yang berfungsi dalam dua "level" konteks yang berbeda, dengan status berbeda yang ada secara independen di level aplikasi dan permintaan.Kenyataannya adalah bahwa "aplikasi konteks" berpotensi cukup nama menyesatkan, karena
app.app_context()
merupakan suatu konteks per-permintaan , persis sama dengan "permintaan konteks" . Anggap saja sebagai "lite konteks permintaan", hanya diperlukan dalam kasus di mana Anda memerlukan beberapa variabel yang biasanya memerlukan konteks permintaan, tetapi Anda tidak memerlukan akses ke objek permintaan apa pun (misalnya ketika menjalankan operasi batch DB dalam skrip shell). Jika Anda mencoba dan memperluas konteks aplikasi untuk mencakup lebih dari satu konteks permintaan, Anda meminta masalah. Jadi, daripada pengujian saya di atas, Anda sebaiknya menulis kode seperti ini dengan konteks Flask:Yang akan memberikan hasil yang diharapkan:
sumber