python - 有没有办法在Python中复制任意生成器?

标签 python generator immutability

函数式编程最著名的功能是惰性求值和无限列表。在Python中,通常使用生成器来实现这些功能。但函数式编程的原则之一是不变性,而生成器也不是一成不变的。恰好相反。每次在生成器上调用 next() 时,它都会更改其内部状态。

一个可能的解决方法是在调用 next() 之前复制生成器。这适用于某些生成器,例如 count()。 (也许 count() 不是生成器?)

from itertools import count

count_gen = count()
count_gen_copy = copy(count_gen)
print(next(count_gen), next(count_gen), next(count_gen))  # => 0 1 2
print(next(count_gen_copy), next(count_gen_copy), next(count_gen_copy))  # => 0 1 2

但是如果我定义自己的生成器,例如 my_count(),我无法复制它。

def my_count(n=0):
    while True:
        yield n
        n += 1


my_count_gen = my_count()
my_count_gen_copy = copy(my_count_gen)
print(next(my_count_gen), next(my_count_gen), next(my_count_gen))
print(next(my_count_gen_copy), next(my_count_gen_copy), next(my_count_gen_copy))

当我尝试执行copy(my_count_gen)时收到错误消息:TypeError: can't pickle Generator objects

有没有办法解决这个问题,或者还有其他方法吗?

也许问这个问题的另一种方式是:当 copy() 复制 copy_gen 时,它在复制什么?

谢谢。

附注如果我使用 __iter__() 而不是 copy(),则 __iter__() 版本的行为与原始版本类似。

my_count_gen = my_count()
my_count_gen_i = my_count_gen.__iter__()
print(next(my_count_gen), next(my_count_gen), next(my_count_gen))  # => 0 1 2
print(next(my_count_gen_i), next(my_count_gen_i), next(my_count_gen_i))  # => 3 4 5

最佳答案

无法在 Python 中复制任意生成器。手术根本没有意义。生成器可能依赖于各种其他不可复制的资源,例如文件句柄、数据库连接、锁、工作进程等。如果生成器持有锁并且您复制了它,那么锁会发生什么情况?如果生成器位于数据库事务中并且您复制它,事务会发生什么?

您认为可复制生成器的东西根本不是生成器。它们是其他迭代器类的实例。如果你想编写自己的迭代器类,你可以:

class MyCount:
    def __init__(self, n=0):
        self._n = n
    def __iter__(self):
        return self
    def __next__(self):
        retval = self._n
        self._n += 1
        return retval

您以这种方式编写的某些迭代器甚至可能是可以合理复制的。其他人,copy.copy会做一些完全不合理且无用的事情。

关于python - 有没有办法在Python中复制任意生成器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63892520/

相关文章:

c# - 比较不可变数据类型

javascript - 错误 : Attempting to set key on an object that is immutable and has been frozen

python - 将 subprocess.call 与 mysqldump 一起使用

python - 为什么我的多索引数据框有重复的索引值?

Python - 根据提供的模式生成文件名

node.js - NodeJS在普通函数内调用生成器函数

struct - 返回 Julia 中字段已更改的新结构

python - 如何限制字典的大小?

python - 如何从文件中读取 float ?

ruby-on-rails - Ruby on Rails 生成模型字段 :type - what are the options for field:type?