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 return
entah 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 return
entah bagaimana memotong manajer konteks ?
Jawaban:
Ya, itu bertindak seperti finally
blok demi try
blok, 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 with
pernyataan:
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 with
blok di dalam try..except
blok yang biasanya tidak sesuai dengan yang diinginkan.
Process.terminate()
adalah satu dari sedikit (satu-satunya?) Skenario yang tidak menjamin panggilan finally
pernyataan: "Perhatikan bahwa keluar penangan dan akhirnya klausa, dll., Tidak akan dieksekusi. "
with
blok, apakah jaminan berlaku selama generator terus menghasilkan nilai? selama referensi apa saja itu? Yaitu apakah saya perlu menggunakan del
atau 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 )
finally
keywrod adalah: def test(): try: return True; finally: return False
.
Iya. Secara lebih umum, __exit__
metode Manajer Pernyataan Dengan Pernyataan memang akan dipanggil jika terjadi return
dari 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'
else
dapat ditambahkanwith
untuk mengatasitry with except
masalah itu. sunting: ditambahkan ke bahasa