如何检查是否使用了发电机?

4

如何判断是否使用了生成器?即:

def code_reader(code):
   for c in code:
        yield c

code_rdr = code_reader(my_code)

a = code_rdr.next()

foo(code_rdr)

在调用foo之后,我想知道code_rdr上是否由foo调用了.next()。 当然,我可以通过一些带有next()调用计数器的类来包装它。 有没有简单的方法来实现这个功能?

获取foo返回的项目索引怎么样,例如code.index(foo(code_rdr))?我知道,对于重复项来说不是完美的,但这是一个选项。 - Ma0
@Ev.Kounis:但是 foo 很可能是一个黑盒... - Willem Van Onsem
另一个相关的重复问题:https://dev59.com/PVgR5IYBdhLWcg3wd9AV - Chris_Rands
@WillemVanOnsem 意思是什么?☺ - Ma0
2个回答

10
Python 3.2+提供了inspect.getgeneratorstate()函数。因此,您可以简单地使用inspect.getgeneratorstate(gen) == 'GEN_CREATED'
>>> import inspect
>>> gen = (i for i in range(3))
>>> inspect.getgeneratorstate(gen)
'GEN_CREATED'
>>> next(gen)
0
>>> inspect.getgeneratorstate(gen)
'GEN_SUSPENDED'

它在某些特殊情况下解决了生成器未预先使用<code>foo</code>的问题。在我的用例中,code_rdr将已经启动。 - www
抱歉,我不明白,但这似乎是一个不同的问题,如果你是在说next()已经被调用了? - Chris_Rands
1
@www 好的,你可以比较调用 foo 前后 inspect.getgeneratorlocals()return 值,但并不是所有情况都适用(例如如果你的生成器是 (c for c in 'aaa'))。无论如何,我建议你将其作为一个新问题提出,并使用不同的标题等,这是一个相当不同的问题,这样你会得到更多的关注。 - Chris_Rands

0

我已经使用了附加的可能答案中的想法,下面重新定义了code_reader函数:

def code_reader(code):
length = len(code)
i = 0
while i < length:
    val = (yield i)
    if val != 'position':
        yield code[i]
        i += 1

通过在 I 上使用 .send('position'),我将知道下一个要生成的项目的位置,即:
a = code_reader("foobar")

print a.next()
print a.send('position')
print a.next()
print a.send('position')
print a.send('position')
print a.next()
print a.send('position')

输出:

0
0
f
1
1
o
2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接