最后在 Python 3 生成器中尝试

try-finally in Python 3 generator

我遇到了Python3代码的片段:

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

print(next(gen()))

我运行之后,我一开始以为输出应该是:

1

但实际上结果是:

stop
1

怎么会这样?幕后发生了什么?

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

正在对生成器对象进行垃圾回收时执行 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

循环在生成器关闭时终止,如果您不保存对它的引用,它会自动发生。一旦发生这种情况,try 语句保证 finally 块在生成器对象被垃圾回收之前执行。比较:

>>> next(gen())
stop
1

>>> x = gen()
>>> next(x)
1