是否有Python函数检查生成器是否已启动?


问题内容

我尝试定义一个生成器函数mycount(),可以使用该生成器函数将其重置,send(0)如下例所示。一切正常,除非当我使用send(0)尚未启动的新生成器对象时。在这种情况下,它给出一个TypeError。是否有任何函数可以检查生成器是否已启动,或者在这种情况下是否必须捕获TypeError并创建新的生成器对象mycount(0)

def mycount(value):
    while True:
        v = yield value
        if v == None:
            value = value + 1
        else:
            value = v

g = mycount(3)
print(next(g))    # prints 3
print(next(g))    # prints 4
print(g.send(0))  # prints 0
print(next(g))    # prints 1
print(next(g))    # prints 2

g2 = mycount(3)
g2.send(0)
# TypeError: can't send non-None value to a just-started generator

问题答案:

为避免将非None值发送给刚启动的生成器,您需要先调用nextsend(None)。我同意其他人的观点,David
Beazley的协程装饰器(在python
3.x中,您需要调用__next__()function而不是next())是一个不错的选择。尽管特定的装饰器很简单,但我还成功地使用了copipes库,该库很好地实现了Beazley演示文稿中的许多实用程序,包括协程。

关于是否可以检查生成器是否已启动-在Python
3中,可以使用inspect.getgeneratorstate。这在Python
2中不可用,但是CPython实现是纯python,并且不依赖于Python
3的任何新功能,因此您可以用相同的方式检查自己:

if generator.gi_running:
    return GEN_RUNNING
if generator.gi_frame is None:
    return GEN_CLOSED
if generator.gi_frame.f_lasti == -1:
    return GEN_CREATED
return GEN_SUSPENDED

具体来说,g2如果启动inspect.getgeneratorstate(g2) != inspect.GEN_CREATED