考虑以下 Python 2.x 代码片段。
from __future__ import print_function
class myfile(file):
def __exit__(self, *excinfo):
print("__exit__ called")
super(myfile, self).__exit__(*excinfo)
def my_generator(file_name):
with myfile(file_name) as fh:
for line in fh:
yield line.strip()
gen = my_generator('file.txt')
print(next(gen))
print("Before del")
del gen
print("After del")
此脚本的输出(给定的 file.txt 有多于一行)是:
Line 1 from file
Before del
__exit__ called
After del
我对 __exit__
调用特别感兴趣。
是什么触发了他的方法的执行?据我们所知,代码永远不会离开 with
语句(它在 yield
语句之后“停止”并且永远不会继续)。当生成器的引用计数降为 0 时,是否保证 __exit__
被调用?
最佳答案
在回收一个生成器对象时,Python 调用它的 close
方法,在它的最后一个 yield
点引发一个 GeneratorExit
异常,如果尚未完成执行。当此 GeneratorExit
传播时,它会触发您使用的上下文管理器的 __exit__
方法。
这是在 Python 2.5 中引入的,in the same PEP as send
and yield expressions .在此之前,您不能在带有 finally
的 try
中 yield
,并且如果 with
语句已经存在-2.5,你也无法在其中 yield
。
关于python - 从上下文管理器的语句和 __exit__ 方法中产生,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44005817/