關於 __exit__ 的行為
概要
這陣子在使用 with
語句時,發現 __exit__
會造成語句中宣告的參數有未繫結的可能性。
如以下範例:
class Foo:
bar = "bar"
def __enter__(self) -> Self:
return self
def __exit__(self, *args) -> bool:
do_something()
return True
with Foo() as foo:
example = foo.bar
print(example) # example may be unbound
在網路上也找不太到文件,因此做了一些測試
說明
如果是要離開前後文管理器
class Foo:
bar = "bar"
def __enter__(self) -> Self:
return self
def __exit__(self, *args) -> None:
do_something()
with Foo() as foo:
example = foo.bar
print(example)
# bar
如果是要壓制例外
class Ignore:
def __enter__(self) -> None:
pass
def __exit__(self, *args) -> bool:
return True
with Ignore():
raise Exception()
print("foo")
# foo
解釋
經過測試後,發現 __exit__
方法會有以下兩種行為。
在回傳任何屬於
True
的資料型態時,會壓制with
語句中發生的例外,直接脫離區塊。如:
True
,1
,"foo"
,["bar"]
在回傳任何屬於
False
的資料型態時,會照常提出例外。如:
None
,False
,0
,""
,[]
若將回傳型態提示為 bool
,同時會存在 True
的壓制與 False
的照常提出例外兩種可能性。
編輯器會進而判斷語句中的操作有未完成的可能性,進一步提出未繫結可能性的警告。
Last updated