如何判断发电机是否刚刚启动? [英] How can I tell whether a generator was just-started?
问题描述
我想要一个功能is_just_started
,其功能如下:
I'd like a function, is_just_started
, which behaves like the following:
>>> def gen(): yield 0; yield 1
>>> a = gen()
>>> is_just_started(a)
True
>>> next(a)
0
>>> is_just_started(a)
False
>>> next(a)
1
>>> is_just_started(a)
False
>>> next(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> is_just_started(a)
False
如何实现此功能?
我查看了.gi_running
属性,但该属性似乎用于其他用途.
I looked at the .gi_running
attribute but it appears to be used for something else.
如果我知道需要发送到生成器的第一个值,则可以执行以下操作:
If I know the first value that needs to be sent into the generator, I can do something like this:
def safe_send(gen, a):
try:
return gen.send(a)
except TypeError as e:
if "just-started" in e.args[0]:
gen.send(None)
return gen.send(a)
else:
raise
但是,这似乎很可恶.
However, this seems abhorrent.
推荐答案
这仅适用于Python 3.2 +:
This only works in Python 3.2+:
>>> def gen(): yield 0; yield 1
...
>>> a = gen()
>>> import inspect
>>> inspect.getgeneratorstate(a)
'GEN_CREATED'
>>> next(a)
0
>>> inspect.getgeneratorstate(a)
'GEN_SUSPENDED'
>>> next(a)
1
>>> inspect.getgeneratorstate(a)
'GEN_SUSPENDED'
>>> next(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> inspect.getgeneratorstate(a)
'GEN_CLOSED'
因此,请求的功能是:
import inspect
def is_just_started(gen):
return inspect.getgeneratorstate(gen) == inspect.GEN_CREATED:
出于好奇,我调查了CPython以弄清它是如何确定的……显然,它查看的是generator.gi_frame.f_lasti
,它是字节码中最后一次尝试执行的指令的索引".如果它是-1
,则尚未启动.
Out of curiosity, I looked into CPython to figure out how it was determining this... Apparently it looks at generator.gi_frame.f_lasti
which is the "index of last attempted instruction in bytecode". If it's -1
then it hasn't started yet.
这是py2版本:
def is_just_started(gen):
return gen.gi_frame is not None and gen.gi_frame.f_lasti == -1
这篇关于如何判断发电机是否刚刚启动?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!