Hãy xem xét những điều sau đây:
with open(path, mode) as f:
return [line for line in f if condition]
Tập tin sẽ được đóng đúng cách, hoặc bằng returncách nào đó bỏ qua trình quản lý bối cảnh ?
Hãy xem xét những điều sau đây:
with open(path, mode) as f:
return [line for line in f if condition]
Tập tin sẽ được đóng đúng cách, hoặc bằng returncách nào đó bỏ qua trình quản lý bối cảnh ?
Câu trả lời:
Vâng, nó hoạt động giống như finallykhối sau một trykhối, tức là nó luôn luôn thực thi (trừ khi quá trình python kết thúc theo một cách khác thường).
Nó cũng được đề cập trong một trong các ví dụ về PEP-343 là đặc điểm kỹ thuật cho withtuyên bố:
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).
Tuy nhiên, một điều đáng nói là bạn không thể dễ dàng bắt gặp các ngoại lệ do open()cuộc gọi ném mà không đặt toàn bộ withkhối bên trong một try..exceptkhối thường không phải là thứ mà người ta muốn.
Process.terminate()là một trong số ít kịch bản (duy nhất?) Không đảm bảo cuộc gọi của một finallytuyên bố: "Lưu ý rằng các trình xử lý thoát và cuối cùng là mệnh đề, v.v., sẽ không Thực thi."
withkhối, liệu bảo đảm có giữ được miễn là trình tạo giữ các giá trị không? miễn là có gì tham khảo nó? Tức là tôi cần sử dụng delhoặc gán một giá trị khác cho biến chứa đối tượng trình tạo?
ValueError: I/O operation on closed file..
Đúng.
def example(path, mode):
with open(path, mode) as f:
return [line for line in f if condition]
.. nó khá nhiều tương đương với:
def example(path, mode):
f = open(path, mode)
try:
return [line for line in f if condition]
finally:
f.close()
Chính xác hơn, __exit__phương thức trong trình quản lý bối cảnh luôn được gọi khi thoát khỏi khối (bất kể ngoại lệ, trả về, v.v.). __exit__Phương thức của đối tượng tệp chỉ gọi f.close()(ví dụ ở đây trong CPython )
finallykeywrod là : def test(): try: return True; finally: return False.
Đúng. Tổng quát hơn, __exit__phương thức của Trình quản lý bối cảnh với câu lệnh thực sự sẽ được gọi trong trường hợp returntừ bên trong bối cảnh. Điều này có thể được kiểm tra với những điều sau đây:
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()
Đầu ra là:
Entering context.
Returning inside with-statement.
EXITING context.
Đầu ra ở trên xác nhận rằng __exit__đã được gọi mặc dù sớm return. Như vậy, người quản lý bối cảnh không được bỏ qua.
Có, nhưng có thể có một số tác dụng phụ trong các trường hợp khác, bởi vì nó có thể làm một cái gì đó (như bộ đệm xả) trong __exit__khối
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'
elsecó thể được thêm vàowithđể giải quyếttry with exceptvấn đề đó . chỉnh sửa: thêm vào ngôn ngữ