最后在Python 3生成器中尝试

时间:2019-05-09 15:31:19

标签: python python-3.x generator try-except

我遇到了一段Python 3代码:

def gen():
    try:
        while True:
            yield 1
    finally:
        print("stop")

print(next(gen()))

运行它之后,我首先想到的输出应该是:

1

但是实际上结果是:

stop
1

这怎么可能发生?引擎盖下发生了什么事?

如果我运行for i in gen(): print(i),将会出现一个无限循环,这正是我所期望的。这里的fornext有什么区别?

2 个答案:

答案 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