您可以return
在生成器中使用一次;它在不产生任何结果的情况下停止迭代,因此提供了一个明确的替代方案来让函数超出范围。所以使用yield
将函数变成一个生成器,但在它之前return
终止生成器,然后再产生任何东西。
>>> def f():
... return
... yield
...
>>> list(f())
[]
我不确定它是否比您所拥有的要好得多——它只是用无操作if
语句替换了无操作yield
语句。但它更惯用。请注意,仅使用yield
是行不通的。
>>> def f():
... yield
...
>>> list(f())
[None]
为什么不直接使用iter(())
?
这个问题专门询问了一个空的生成器函数。出于这个原因,我认为这是一个关于 Python 语法内部一致性的问题,而不是一个关于创建空迭代器的最佳方法的问题。
如果问题实际上是关于创建空迭代器的最佳方法,那么您可能同意Zectbumo关于使用的iter(())
替代方法。但是,重要的是要注意iter(())
不返回函数!它直接返回一个空的可迭代对象。假设您正在使用一个 API,该 API 需要一个每次调用时返回一个可迭代对象的可调用对象,就像普通的生成器函数一样。你必须做这样的事情:
def empty():
return iter(())
(信用应该归功于 Unutbu给出了这个答案的第一个正确版本。)
现在,您可能会发现上面的内容更清楚,但我可以想象它不太清楚的情况。考虑这个一长串(人为的)生成器函数定义的例子:
def zeros():
while True:
yield 0
def ones():
while True:
yield 1
...
在那长长的列表的最后,我宁愿看到里面有 ayield
的东西,像这样:
def empty():
return
yield
或者,在 Python 3.3 及更高版本中(如DSM所建议),此:
def empty():
yield from ()
关键字的存在yield
一目了然地表明这只是另一个生成器函数,与所有其他函数完全相同。需要更多时间才能看到该iter(())
版本正在执行相同的操作。
这是一个微妙的区别,但老实说,我认为yield
基于 - 的函数更具可读性和可维护性。
另请参阅user3840170的这个很好的答案,它用于dis
说明为什么这种方法更可取的另一个原因:它在编译时发出的指令最少。