<p>您可以在生成器中使用<code>return</code>;它停止迭代而不产生任何结果,因此提供了一个显式的替代方案,以使函数超出范围。因此,使用<code>yield</code>将函数转换为生成器,但在它之前使用<code>return</code>在生成任何内容之前终止生成器。</p>
<pre><code>>>> def f():
... return
... yield
...
>>> list(f())
[]
</code></pre>
<p>我不确定它是否比你现有的更好——它只是用一个no op<code>if</code>语句替换了一个no op<code>yield</code>语句。但它更为地道。注意,仅仅使用<code>yield</code>是行不通的。</p>
<pre><code>>>> def f():
... yield
...
>>> list(f())
[None]
</code></pre>
<h3>为什么不直接使用<code>iter(())</code>?</h3>
<p>这个问题专门询问一个空的<em>生成器函数</em>。因此,我认为这是一个关于Python语法内部一致性的问题,而不是一个关于创建空迭代器的最佳方法的问题。</p>
<p>如果问题实际上是关于创建空迭代器的最佳方法,那么您可能同意使用<a href="https://stackoverflow.com/a/26271684/577088">Zectbumo</a>来代替<code>iter(())</code>。但是,必须注意<code>iter(())</code>不返回函数!它直接返回一个空的iterable。假设您正在使用一个API,它期望一个<em>返回</em>一个iterable的可调用函数。你必须这样做:</p>
<pre><code>def empty():
return iter(())
</code></pre>
<p>(应该感谢<a href="https://stackoverflow.com/a/13243922/577088">Unutbu</a>给出了这个答案的第一个正确版本。)</p>
<p>现在,你可能会发现上面说得更清楚,但我可以想象在什么情况下它会不那么清楚。考虑一下这个长列表(人为的)生成器函数定义的示例:</p>
<pre><code>def zeros():
while True:
yield 0
def ones():
while True:
yield 1
...
</code></pre>
<p>在这个长列表的末尾,我更希望看到一些包含<code>yield</code>的内容,比如:</p>
<pre><code>def empty():
return
yield
</code></pre>
<p>或者,在Python 3.3及更高版本中(如<a href="https://stackoverflow.com/a/13243920/577088">DSM</a>所建议的),这:</p>
<pre><code>def empty():
yield from ()
</code></pre>
<p>关键字<code>yield</code>的出现使我们一眼就能清楚地看到,这只是另一个生成器函数,与所有其他函数完全一样。要花更多的时间才能看到<code>iter(())</code>版本也在做同样的事情。</p>
<p>这是一个微妙的区别,但我确实认为基于<code>yield</code>的函数更具可读性和可维护性。</p>