2009-09-09 2 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

Вы клонируете генератор? Generators can't be cloned.

Копирование ответ Габриэля 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 

г и 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

Я новичок в этом, и я просто попытался использовать «доходность». Поэтому я лучше прочитаю о них. Да, когда я удалил «выход», ошибка исчезла. Спасибо –

+0

Кажется, ссылка мертва. – antonagestam

+0

@antonagestam Исправлено. – wRAR

0

Это происходит во многих случаях, когда один случайно пытается клонировать итератор классу. Например, в PIL попытка клонирования PixelAccessImage выдает эту ошибку.

Приведите пример, где pixels = image.load(). Вместо того, чтобы пытаться сделать что-то вроде pixels_copy = copy.copy(pixels), вам нужно скопировать базовый объект, а затем создать итератор. Итак, замените этот фрагмент кода на pixels_copy = image.copy().load().

Смежные вопросы