2009-09-09 95 views
3

我一直在使用這種複製方法很長一段時間,在很多需要它的類中。Python:copy.deepcopy產生錯誤

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行」之前重複好幾次說我在這裏複製。

回答

9

您是在克隆發生器嗎?加布裏埃爾Genellina這裏Generators can't be cloned.

複製答案:


沒有「克隆」一臺發電機的辦法:

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Ç
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 - 但是這太魔力。爲我的口味...

+0

我是新來的,我剛剛嘗試過使用'yield'。所以我最好更多地閱讀它們。是的,當我刪除'yield'時,錯誤消失了。謝謝 – 2009-09-09 19:52:01

+0

似乎鏈接已死亡。 – antonagestam 2013-08-28 11:12:39

+0

@antonagestam固定。 – wRAR 2013-08-28 16:37:36

0

在很多情況下,如果您不小心嘗試將迭代器克隆到類中,就會發生這種情況。例如,在PIL中,試圖克隆ImagePixelAccess將引發此錯誤。

舉一個例子,其中pixels = image.load()。與其試圖做類似pixels_copy = copy.copy(pixels)的事情,您必須複製基礎對象,然後生成迭代器。所以,用pixels_copy = image.copy().load()替換那段代碼。