<p>是的,您可以在生成器中使用<code>with</code>语句而不会出现问题。Python将正确处理上下文,因为垃圾收集时生成器将关闭。在</p>
<p>在生成器中,<code>GeneratorExit</code>异常在生成器被垃圾回收时引发,因为它将在此时关闭:</p>
<pre><code>>>> 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
</code></pre>
<p>这是<a href="https://www.python.org/dev/peps/pep-0342/" rel="nofollow">PEP 342</a>的一部分,关闭生成器将引发异常。获取一个没有引用的生成器应该始终关闭该生成器,如果Jython没有关闭生成器,我会认为这是一个bug。在</p>
<p>见规范概要第4点和第5点:</p>
<blockquote>
<ol start="4">
<li><p>Add a <code>close()</code> method for generator-iterators, which raises <code>GeneratorExit</code> at the point where the generator was paused. If
the generator then raises <code>StopIteration</code> (by exiting normally, or
due to already being closed) or <code>GeneratorExit</code> (by not catching
the exception), <code>close()</code> returns to its caller. If the generator
yields a value, a <code>RuntimeError</code> is raised. If the generator
raises any other exception, it is propagated to the caller.
<code>close()</code> does nothing if the generator has already exited due to
an exception or normal exit.</p></li>
<li><p>Add support to ensure that <code>close()</code> is called when a generator
iterator is garbage-collected.</p></li>
</ol>
</blockquote>
<p>唯一需要注意的是,在Jython、IronPython和pypyy中,不能保证垃圾收集器在退出解释器之前运行。如果这对应用程序很重要,可以显式关闭生成器:</p>
^{pr2}$
<p>或显式触发垃圾回收。在</p>