Ian*_*son 51 python class with-statement python-3.x
我有以下代码:
class Test:
def __init__(self, name):
self.name = name
def __enter__(self):
print(f'entering {self.name}')
def __exit__(self, exctype, excinst, exctb) -> bool:
print(f'exiting {self.name}')
return True
with Test('first') as test:
print(f'in {test.name}')
test = Test('second')
with test:
print(f'in {test.name}')
Run Code Online (Sandbox Code Playgroud)
运行它会产生以下输出:
class Test:
def __init__(self, name):
self.name = name
def __enter__(self):
print(f'entering {self.name}')
def __exit__(self, exctype, excinst, exctb) -> bool:
print(f'exiting {self.name}')
return True
with Test('first') as test:
print(f'in {test.name}')
test = Test('second')
with test:
print(f'in {test.name}')
Run Code Online (Sandbox Code Playgroud)
但我预计它会产生:
entering first
exiting first
entering second
in second
exiting second
Run Code Online (Sandbox Code Playgroud)
为什么我的第一个示例中的代码没有被调用?
Sil*_*olo 60
该__enter__方法应该返回上下文对象。with ... as ...使用 的返回值__enter__来确定要给您什么对象。由于您__enter__没有返回任何内容,因此它隐式返回None,因此test也是None。
with Test('first') as test:
print(f'in {test.name}')
test = Test('second')
with test:
print(f'in {test.name}')
Run Code Online (Sandbox Code Playgroud)
也test没有。然后test.name就是一个错误。该错误被引发,因此Test('first').__exit__被调用。__exit__回报True,这表明错误已被处理(本质上,你的__exit__行为就像一个except块),因此代码在第一个with块之后继续,因为你告诉Python一切都很好。
考虑
def __enter__(self):
print(f'entering {self.name}')
return self
Run Code Online (Sandbox Code Playgroud)
您也可能会考虑不返回True,__exit__除非您确实打算无条件抑制块中的所有错误(并且完全理解抑制其他程序员的错误以及各种系统信号的后果KeyboardInterrupt)StopIteration
| 归档时间: |
|
| 查看次数: |
3188 次 |
| 最近记录: |