Question

J'utilise cette méthode de copie depuis un certain temps, dans de nombreuses classes qui en avaient besoin.

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

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

Il a soudainement commencé à produire cette erreur:

     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__()
>>> 

les lignes qui incluent les références aux lignes 338, 162, 255, 189 ont été répétées plusieurs fois avant la 'ligne 338' que j'ai copiée ici.

Était-ce utile?

La solution

Êtes-vous en train de cloner un générateur? Les générateurs ne peuvent pas être clonés.

Copie de la réponse de Gabriel Genellina ici:

Il n’existe aucun moyen de " cloner " un générateur:

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>

Vous pouvez le faire avec une fonction de générateur car elle agit en tant que "générateur"
usine ", construisant un nouveau générateur lorsque appelé. Même en utilisant le Python C
API, pour créer un générateur, il faut un objet cadre - et il n’ya aucun moyen de le faire
créer un objet cadre "à la volée" que je connaisse: (

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 et g2 partagent le même cadre d'exécution, ils ne sont donc pas indépendants. Il
Il n’est pas facile de créer un nouveau cadre en Python:

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

On pourrait essayer d’utiliser PyFrame_New - mais c’est trop magique à mon goût ...

Autres conseils

Cela se produit souvent lorsque l’on essaie accidentellement de cloner l’itérateur dans une classe. Par exemple, dans PIL, essayer de cloner le PixelAccess d'une image provoquera cette erreur.

Prenons un exemple où pixels = image.load () . Au lieu d'essayer de faire quelque chose comme pixels_copie = copie.copie (pixels) , vous devez copier l'objet de base puis produire un itérateur. Donc, remplacez cette partie de code par pixels_copy = image.copy (). Load () .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top