我遇到了一段Python 3代码:
def gen():
try:
while True:
yield 1
finally:
print("stop")
print(next(gen()))
运行它之后,我首先想到的输出应该是:
1
但是实际上结果是:
stop
1
这怎么可能发生?引擎盖下发生了什么事?
如果我运行for i in gen(): print(i)
,将会出现一个无限循环,这正是我所期望的。这里的for
和next
有什么区别?
答案 0 :(得分:5)
finally子句在生成器对象的垃圾回收上执行。
请考虑以下两种情况:
def gen():
try:
while True:
yield 1
finally:
print("stop")
g1 = gen(); print('first time')
print(next(g1))
g2 = gen(); print('second time') # no stop will be printed because we haven't hit the finally clause yet
def gen():
try:
while True:
yield 1
finally:
print("stop")
g = gen(); print('first time')
print(next(g))
g = gen(); print('second time') # stop will be printed when the first object g was assigned to is garbage collected
答案 1 :(得分:4)
当生成器关闭时,循环终止,如果不保存对它的引用,循环将自动发生。一旦发生这种情况,try
语句将保证在对生成器对象进行垃圾回收之前执行finally
块。比较:
>>> next(gen())
stop
1
使用
>>> x = gen()
>>> next(x)
1