我知道在Python中,生成器是被延迟调用的。例如:
>>> def G():
... print('this was evaluated now 1')
... yield 1
... print('this was evaluated now 2')
... yield 2
...
>>> g = G()
>>> next(g)
this was evaluated now 1
1
>>> next(g)
this was evaluated now 2
2
只有在调用第一个next(g)
之后,才对行print('this was evaluated now 1')
求值。你知道吗
我想知道是否有一种简单的方法可以不延迟地调用生成器。这意味着在调用g = G()
时,函数将计算第一个yield
结果之前的所有内容,而不会实际产生任何结果。然后,在第一次调用next(g)
时,将生成已经计算的结果,并且还将计算第二个yield
结果之前的所有内容。等等。你知道吗
如何做到这一点?你知道吗
以下是此非懒惰方案下的预期行为:
>>> g = G()
this was evaluated now 1
>>> next(g)
1
this was evaluated now 2
>>> next(g)
2
以下是一个解决方案尝试,但不起作用:
>>> class NonLazyGenerator():
... def __init__(self,G):
... self.g = G()
... self.next_value = next(self.g)
...
... def __next__(self):
... current_value = self.next_value
... try:
... self.next_value = next(self.g)
... except StopIteration:
... pass
... return current_value
...
>>> g = NonLazyGenerator(G)
this was evaluated now 1
>>> next(g)
this was evaluated now 2
1
>>> next(g)
2
这失败了,因为值只在return
语句之后产生,而计算下一个yield
之前的所有内容都发生在return
语句之前。这个例子让我意识到,可能无法执行我正在寻找的任务,因为它需要在函数返回后执行步骤(可能需要多线程)。你知道吗
你可以为它编写一些装饰程序,例如:
然后您可以简单地装饰您的普通发电机:
其工作原理如下:
信贷:这是由@L3viathan答案启发的
在这个版本中,itertools.tee用于存储包装器在原始生成器后面生成的值。你知道吗
相关问题 更多 >
编程相关推荐