Python空生成器函数 [英] Python Empty Generator Function

查看:75
本文介绍了Python空生成器函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在python中,可以通过将yield关键字放在函数主体中来轻松定义迭代器函数,例如:

In python, one can easily define an iterator function, by putting the yield keyword in the function's body, such as:

def gen():
    for i in range(100):
        yield i

我该如何定义不产生任何值的生成器函数(生成0个值),以下代码不起作用,因为python无法知道它应该是生成器而不是普通函数:

How can I define a generator function that yields no value (generates 0 values), the following code doesn't work, since python cannot know that it is supposed to be an generator and not a normal function:

def empty():
    pass

我可以做类似的事情

def empty():
    if False:
        yield None

但是那将是非常丑陋的.有什么好的方法可以实现空的迭代器功能?

But that would be very ugly. Is there any nice way to realize an empty iterator function?

推荐答案

您可以在生成器中使用一次return;它会停止迭代而不会产生任何结果,因此提供了一种使函数超出范围的明确选择.因此,请使用yield将函数转换为生成器,但在使用return之前将其终止以在生成任何内容之前终止生成器.

You can use return once in a generator; it stops iteration without yielding anything, and thus provides an explicit alternative to letting the function run out of scope. So use yield to turn the function into a generator, but precede it with return to terminate the generator before yielding anything.

>>> def f():
...     return
...     yield
... 
>>> list(f())
[]

我不确定它是否比您拥有的要好得多-它只是将no-op if语句替换为no-op yield语句.但这更惯用了.请注意,仅使用yield无效.

I'm not sure it's that much better than what you have -- it just replaces a no-op if statement with a no-op yield statement. But it is more idiomatic. Note that just using yield doesn't work.

>>> def f():
...     yield
... 
>>> list(f())
[None]

为什么不只使用iter(())?

这个问题专门询问一个空的生成器函数.因此,我将其视为关于Python语法的内部一致性的问题,而不是一般而言有关创建空迭代器的最佳方法的问题.

Why not just use iter(())?

This question asks specifically about an empty generator function. For that reason, I take it to be a question about the internal consistency of Python's syntax, rather than a question about the best way to create an empty iterator in general.

如果问题实际上是关于创建空迭代器的最佳方法,那么您可能会同意 Zectbumo 关于使用iter(())代替.但是,重要的是要注意iter(())不会返回函数!它直接返回一个空的Iterable.假设您正在使用一个期望每次调用返回的可调用对象的API,就像普通的生成器函数一样.您将必须执行以下操作:

If question is actually about the best way to create an empty iterator, then you might agree with Zectbumo about using iter(()) instead. However, it's important to observe that iter(()) doesn't return a function! It directly returns an empty iterable. Suppose you're working with an API that expects a callable that returns an iterable each time it's called, just like an ordinary generator function. You'll have to do something like this:

def empty():
    return iter(())

(信用应转到 Unutbu ,以给出此答案的第一个正确版本.)

(Credit should go to Unutbu for giving the first correct version of this answer.)

现在,您可能会发现上面的内容更加清晰,但是我可以想象一下情况不太清楚的情况.考虑以下(伪造的)生成器函数定义列表的示例:

Now, you may find the above clearer, but I can imagine situations in which it would be less clear. Consider this example of a long list of (contrived) generator function definitions:

def zeros():
    while True:
        yield 0

def ones():
    while True:
        yield 1

...

在那长列表的末尾,我宁愿看到其中包含yield的内容,例如:

At the end of that long list, I'd rather see something with a yield in it, like this:

def empty():
    return
    yield

或者,在Python 3.3及更高版本中(如 DSM 所建议),

or, in Python 3.3 and above (as suggested by DSM), this:

def empty():
    yield from ()

yield关键字的存在使我们一眼就可以看出,这只是另一个生成器函数,与所有其他函数完全一样.要弄清iter(())版本是否正在执行相同的操作,需要花费更多时间.

The presence of the yield keyword makes it clear at the briefest glance that this is just another generator function, exactly like all the others. It takes a bit more time to see that the iter(()) version is doing the same thing.

这是一个细微的差异,但是老实说,我认为基于yield的功能更具可读性和可维护性.

It's a subtle difference, but I honestly think the yield-based functions are more readable and maintainable.

另请参阅 user3840170 中的一个很好的答案,该答案使用dis来说明采用这种方法的另一个原因:它编译时发出最少的指令.

See also this great answer from user3840170 that uses dis to show another reason why this approach is preferable: it emits the fewest instructions when compiled.

这篇关于Python空生成器函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆