gpt4 book ai didi

python - 如何让Python将函数识别为生成器函数?

转载 作者:行者123 更新时间:2023-12-01 03:56:52 25 4
gpt4 key购买 nike

首先,考虑以下代码(接下来我将讨论 subgen() 的几个版本):

>>> def maingen(i):
... print("maingen started")
... yield from subgen(i)
... print("maingen finished")
...
>>> for i in maingen(5):
... print(i)
...

我想编写几个 subgen 生成器函数。

正常的是:

>>> def subgen_1(i):
... yield i + 1
... yield i + 2
... yield i + 3

没有问题,输出符合预期:

maingen started
6
7
8
maingen finished

现在,我想要另一个版本的 subgen 它不会产生任何结果...

如果我尝试这样做:

>>> def subgen_2(i):
... i * 3

我有一个异常(exception):

maingen started
Traceback (most recent call last):
...
TypeError: 'NoneType' object is not iterable

预期:subgen_2 不是生成器函数。

好的,下一步。我可以在某个地方阅读(例如第一个答案 here )我必须引发 StopIteration。 (请注意,作为新手,我无法评论此答案。)

>>> def subgen_3(i):
... i * 3
... raise StopIteration()
...

PEP 479 中所述,“最后,该提案还消除了有关如何终止生成器的困惑:正确的方法是返回,而不是引发StopIteration。” ,我只得到:

maingen started

(没有maingen完成...)

我发现让事情顺利进行的唯一方法是:

>>> def subgen_4(i):
... i * 3
... return
... yield
...

有了这个,我得到:

maingen started
maingen finished
万岁!但这个解决方案并不漂亮......

有人有更好或更Python化的想法吗?

是否可以编写一个装饰器来 secret 添加丑陋的yield语句?

最佳答案

如果您希望子生成器不产生任何结果,则返回一个空迭代器:

def subgen_2(i):
i * 3
return iter([]) #empty iterator

您获得 TypeError: 'NoneType' object is not iterable 的原因是因为没有 yield在你的子生成器中声明它不是一个生成器,而是一个隐式返回 None 的常规函数​​。 .

通过返回一个不产生任何值的有效迭代器,您将能够yield from subgen_2()没有错误并且不会生成任何附加值。

隐藏这个的另一种方法(我真的不明白你为什么想要这样做)是创建一个装饰器,它实际上只是调用你的函数,然后执行 return iter(())yield from [] .

def gen_nothing(f):
@functools.wraps(f)
def wrapper(*args,**kw):
f(*args,**kw)
yield from []
return wrapper

但是这产生的唯一区别是堆栈将需要一个额外的帧用于包装器,这意味着您的回溯消息将有更多的噪音:

Traceback (most recent call last):
File "/Users/Tadhg/Documents/codes/test.py", line 15, in <module>
for i in subgen():
File "/Users/Tadhg/Documents/codes/test.py", line 6, in wrapper
f(*args,**kw)
File "/Users/Tadhg/Documents/codes/test.py", line 12, in subgen
3/0
ZeroDivisionError: division by zero

关于python - 如何让Python将函数识别为生成器函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37303741/

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