gpt4 book ai didi

python - 在生成器中使用 with 语句是否明智?

转载 作者:太空宇宙 更新时间:2023-11-03 11:02:26 25 4
gpt4 key购买 nike

考虑以下 Python 代码:

def values():
with somecontext():
yield 1
yield 2
for v in values():
print(v)
break

在这种情况下,Python 是否保证生成器正确关闭并因此退出上下文?

我意识到,在实践中,由于生成器的引用计数和急切销毁,CPython 中会出现这种情况,但是 Python 是否保证这种行为?我确实注意到它在 Jython 中确实不起作用,所以这应该被视为错误或允许的行为吗?

最佳答案

是的,您可以毫无问题地在生成器中使用 with 语句。 Python 将正确处理上下文,因为生成器将在收集垃圾时关闭。

在生成器中,当生成器被垃圾回收时会引发一个GeneratorExit 异常,因为它会在那个时候关闭:

>>> from contextlib import contextmanager
>>> @contextmanager
... def somecontext():
... print 'Entering'
... try:
... yield None
... finally:
... print 'Exiting'
...
>>> def values():
... with somecontext():
... yield 1
... yield 2
...
>>> next(values())
Entering
Exiting
1

这是 PEP 342 的一部分,其中关闭生成器会引发异常。收割一个没有引用的生成器应该总是关闭那个生成器,如果 Jython 没有关闭生成器我会认为这是一个错误。

请参阅规范摘要的第 4 点和第 5 点:

  1. Add a close() method for generator-iterators, which raises GeneratorExit at the point where the generator was paused. If the generator then raises StopIteration (by exiting normally, or due to already being closed) or GeneratorExit (by not catching the exception), close() returns to its caller. If the generator yields a value, a RuntimeError is raised. If the generator raises any other exception, it is propagated to the caller. close() does nothing if the generator has already exited due to an exception or normal exit.

  2. Add support to ensure that close() is called when a generator iterator is garbage-collected.

唯一需要注意的是,在 Jython、IronPython 和 PyPy 中,不能保证垃圾收集器在退出解释器之前运行。如果这对您的应用程序很重要,您可以明确关闭生成器:

gen = values()
next(gen)
gen.close()

或显式触发垃圾回收。

关于python - 在生成器中使用 with 语句是否明智?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29040534/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com