Python:copy.deepcopy产生错误

时间:2009-09-09 19:32:40

标签: python generator

在很多需要它的类中,我一直在使用这种复制方法。

class population (list):
def __init__ (self):
    pass

def copy(self):
    return copy.deepcopy(self)

它突然开始产生这个错误:

     File "C:\Python26\lib\copy.py", line 338, in _reconstruct
    state = deepcopy(state, memo)
  File "C:\Python26\lib\copy.py", line 162, in deepcopy
    y = copier(x, memo)
  File "C:\Python26\lib\copy.py", line 255, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "C:\Python26\lib\copy.py", line 189, in deepcopy
    y = _reconstruct(x, rv, 1, memo)
  File "C:\Python26\lib\copy.py", line 323, in _reconstruct
    y = callable(*args)
  File "C:\Python26\lib\copy_reg.py", line 93, in __newobj__
    return cls.__new__(cls, *args)
TypeError: object.__new__(generator) is not safe, use generator.__new__()
>>> 

包含对第338,162,255,189行的引用的行在我复制的'第338行'之前重复了很多次。

2 个答案:

答案 0 :(得分:9)

你在克隆发电机吗? Generators can't be cloned.

Gabriel Genellina在这里复制答案:


没有办法“克隆”发电机:

py> g = (i for i in [1,2,3])
py> type(g)()
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
TypeError: cannot create 'generator' instances
py> g.gi_code = code
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
TypeError: readonly attribute
py> import copy
py> copy.copy(g)
Traceback (most recent call last):
...
TypeError: object.__new__(generator) is not safe, use generator.__new__()
py> type(g).__new__
<built-in method __new__ of type object at 0x1E1CA560>

你可以用发电机功能做到这一点,因为它充当了“发电机” 工厂“,在调用时构建一个新的生成器。即使使用Python C
API,创建一个生成器需要一个框架对象 - 而且没有办法 我知道的“动态”创建一个框架对象:(

py> import ctypes
py> PyGen_New = ctypes.pythonapi.PyGen_New
py> PyGen_New.argtypes = [ctypes.py_object]
py> PyGen_New.restype = ctypes.py_object
py> g = (i for i in [1,2,3])
py> g2 = PyGen_New(g.gi_frame)
py> g2.gi_code is g.gi_code
True
py> g2.gi_frame is g.gi_frame
True
py> g.next()
1
py> g2.next()
2

g和g2共享相同的执行帧,因此它们不是独立的。有
在Python中创建新框架并不容易:

py> type(g.gi_frame)()
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
TypeError: cannot create 'frame' instances

有人可以尝试使用PyFrame_New - 但这对我来说太神奇了......

答案 1 :(得分:0)

在许多情况下,当一个人意外地尝试将迭代器克隆到类时,会发生这种情况。例如,在PIL中,尝试克隆PixelAccess的{​​{1}}将抛出此错误。

Image为例。您不必尝试执行pixels = image.load()之类的操作,而是必须复制基础对象,然后生成迭代器。因此,请使用pixels_copy = copy.copy(pixels)替换该段代码。