在python中深度复制生成器

Cai*_*ain 16 python generator

我正在使用发电机功能,说:

def foo():
    i=0
    while (i<10):
         i+=1
         yield i
Run Code Online (Sandbox Code Playgroud)

现在,我希望选择在任意次数的迭代后复制生成器,以便新副本将保留内部状态(在示例中将具有相同的"i"),但现在将独立于原始状态(即迭代)副本不应该改变原来的).

我尝试过使用copy.deepcopy但是我得到了错误:

 "TypeError: object.__new__(generator) is not safe, use generator.__new__()"   
Run Code Online (Sandbox Code Playgroud)

显然,我可以使用带有计数器的常规函数​​来解决这个问题.但我真的在寻找使用发电机的解决方案.

Cor*_*man 9

我能想到三种情况:

  • 生成器没有副作用,您只希望能够回顾已经捕获的结果.您可以考虑使用缓存的生成器而不是真正的生成器.您也可以共享缓存的生成器,如果任何客户端走到您尚未到达的项目,它将会前进.这与tee()方法类似,但是在生成器/缓存本身中执行tee功能而不是要求客户端执行此操作.

  • Generator有副作用,但没有历史记录,您希望能够在任何地方重新启动.考虑将其写为协程,您可以随时传入值.

  • 发电机有副作用和历史,这意味着发电机中的G(x)的状态取决于G(X-1)的结果,所以你不能只是传递X返回到它的任何地方开始.在这种情况下,我认为您需要更具体地了解您要执行的操作,因为结果不仅取决于生成器,还取决于其他数据的状态.在这种情况下,可能有更好的方法.


g.d*_*d.c 5

评论itertools.tee是我的第一个猜测.由于警告你不应该在使用T恤后再推进原始发电机,我可能会写这样的东西来分拆副本:

>>> from itertools import tee
>>>
>>> def foo():
...   i = 0
...   while i < 10:
...     i += 1
...     yield i
...
>>>
>>> it = foo()
>>> it.next()
1
>>> it, other = tee(it)
>>> it.next()
2
>>> other.next()
2
Run Code Online (Sandbox Code Playgroud)