Pertimbangkan yang berikut ini:
with open(path, mode) as f:
return [line for line in f if condition]
Apakah file akan ditutup dengan benar, atau apakah menggunakan returnentah bagaimana memotong manajer konteks ?
Pertimbangkan yang berikut ini:
with open(path, mode) as f:
return [line for line in f if condition]
Apakah file akan ditutup dengan benar, atau apakah menggunakan returnentah bagaimana memotong manajer konteks ?
Jawaban:
Ya, itu bertindak seperti finallyblok demi tryblok, yaitu selalu dijalankan (kecuali proses python berakhir dengan cara yang tidak biasa tentu saja).
Ini juga disebutkan dalam salah satu contoh PEP-343 yang merupakan spesifikasi untuk withpernyataan:
with locked(myLock):
# Code here executes with myLock held. The lock is
# guaranteed to be released when the block is left (even
# if via return or by an uncaught exception).
Namun, sesuatu yang layak disebutkan adalah bahwa Anda tidak dapat dengan mudah menangkap pengecualian yang dilemparkan oleh open()panggilan tanpa menempatkan seluruh withblok di dalam try..exceptblok yang biasanya tidak sesuai dengan yang diinginkan.
Process.terminate()adalah satu dari sedikit (satu-satunya?) Skenario yang tidak menjamin panggilan finallypernyataan: "Perhatikan bahwa keluar penangan dan akhirnya klausa, dll., Tidak akan dieksekusi. "
withblok, apakah jaminan berlaku selama generator terus menghasilkan nilai? selama referensi apa saja itu? Yaitu apakah saya perlu menggunakan delatau menetapkan nilai yang berbeda untuk variabel yang menyimpan objek generator?
ValueError: I/O operation on closed file..
Iya.
def example(path, mode):
with open(path, mode) as f:
return [line for line in f if condition]
..adalah setara dengan:
def example(path, mode):
f = open(path, mode)
try:
return [line for line in f if condition]
finally:
f.close()
Lebih tepatnya, __exit__metode dalam manajer konteks selalu dipanggil saat keluar dari blok (terlepas dari pengecualian, pengembalian, dll). Metode objek file __exit__hanya panggilan f.close()(misalnya di sini di CPython )
finallykeywrod adalah: def test(): try: return True; finally: return False.
Iya. Secara lebih umum, __exit__metode Manajer Pernyataan Dengan Pernyataan memang akan dipanggil jika terjadi returndari dalam konteks. Ini dapat diuji dengan yang berikut:
class MyResource:
def __enter__(self):
print('Entering context.')
return self
def __exit__(self, *exc):
print('EXITING context.')
def fun():
with MyResource():
print('Returning inside with-statement.')
return
print('Returning outside with-statement.')
fun()
Outputnya adalah:
Entering context.
Returning inside with-statement.
EXITING context.
Output di atas mengkonfirmasi bahwa __exit__itu disebut meskipun awal return. Dengan demikian, manajer konteks tidak dilewati.
Ya, tetapi mungkin ada beberapa efek samping dalam kasus lain, karena mungkin harus melakukan sesuatu (seperti buffer flushing) di __exit__blok
import gzip
import io
def test(data):
out = io.BytesIO()
with gzip.GzipFile(fileobj=out, mode="wb") as f:
f.write(data)
return out.getvalue()
def test1(data):
out = io.BytesIO()
with gzip.GzipFile(fileobj=out, mode="wb") as f:
f.write(data)
return out.getvalue()
print(test(b"test"), test1(b"test"))
# b'\x1f\x8b\x08\x00\x95\x1b\xb3[\x02\xff' b'\x1f\x8b\x08\x00\x95\x1b\xb3[\x02\xff+I-.\x01\x00\x0c~\x7f\xd8\x04\x00\x00\x00'
elsedapat ditambahkanwithuntuk mengatasitry with exceptmasalah itu. sunting: ditambahkan ke bahasa