【发布时间】:2019-06-02 06:29:25
【问题描述】:
也许这是一个愚蠢(而且确实不是很实际)的问题,但我之所以问这个问题是因为我无法理解它。
在研究调用上下文管理器中的 return 语句是否会阻止调用 __exit__(不,不会)时,我发现在 __exit__ 和 @ 之间进行类比似乎很常见987654325@ 在 try/finally 块中(例如这里:https://*.com/a/9885287/3471881)因为:
def test():
try:
return True
finally:
print("Good bye")
将执行相同的操作:
class MyContextManager:
def __enter__(self):
return self
def __exit__(self, *args):
print('Good bye')
def test():
with MyContextManager():
return True
这确实帮助我理解了 cm:s 的工作原理,但在玩了一会儿之后,我意识到如果我们返回一些东西而不是打印,这个类比就行不通了。
def test():
try:
return True
finally:
return False
test()
--> False
虽然__exit__ 似乎根本不会回来:
class MyContextManager:
def __enter__(self):
return self
def __exit__(self, *args):
return False
def test():
with MyContextManager():
return True
test()
--> True
这让我想到,也许您实际上无法在 __exit__ 中返回任何内容,但您可以:
class MyContextManager:
def __enter__(self):
return self
def __exit__(self, *args):
return self.last_goodbye()
def last_goodbye(self):
print('Good bye')
def test():
with MyContextManager():
return True
test()
--> Good bye
--> True
请注意,如果我们在 test() 函数中不返回任何内容,这并不重要。
这引出了我的问题:
- 是否不可能从
__exit__内部返回值,如果是,为什么?
【问题讨论】:
-
请注意
__exit__的返回值有一个定义的含义:如果__exit__返回True,那么在with上下文中抛出的任何异常都将被抑制并且不会传播到外部with块。
标签: python python-3.x