deepcopy
de copy
ne copie pas une classe :
>>> class A(object):
>>> ARG = 1
>>> B = deepcopy(A)
>>> A().ARG
>>> 1
>>> B().ARG
>>> 1
>>> A.ARG = 2
>>> B().ARG
>>> 2
Est-ce le seul moyen ?
B(A):
pass
deepcopy
de copy
ne copie pas une classe :
>>> class A(object):
>>> ARG = 1
>>> B = deepcopy(A)
>>> A().ARG
>>> 1
>>> B().ARG
>>> 1
>>> A.ARG = 2
>>> B().ARG
>>> 2
Est-ce le seul moyen ?
B(A):
pass
En général, l'héritage est la bonne voie à suivre, comme les autres affiches l'ont déjà souligné.
Cependant, si vous voulez vraiment recréer le même type avec un nom différent et sans héritage, vous pouvez le faire comme ceci :
class B(object):
x = 3
CopyOfB = type('CopyOfB', B.__bases__, dict(B.__dict__))
b = B()
cob = CopyOfB()
print b.x # Prints '3'
print cob.x # Prints '3'
b.x = 2
cob.x = 4
print b.x # Prints '2'
print cob.x # Prints '4'
Vous devez être prudent avec les valeurs d'attribut mutables :
class C(object):
x = []
CopyOfC = type('CopyOfC', C.__bases__, dict(C.__dict__))
c = C()
coc = CopyOfC()
c.x.append(1)
coc.x.append(2)
print c.x # Prints '[1, 2]' (!)
print coc.x # Prints '[1, 2]' (!)
Comme l'a souligné Florian Brucker, il y a un problème avec les attributs de classe mutables. Vous ne pouvez pas non plus vous contenter de deepcopy(cls.__dict__)
sur de nouveaux objets de style. J'ai fait ce qui suit pour résoudre ce problème pour ce que je fais. Je suis certain que quelqu'un d'assez déterminé pourrait briser ça. Mais, cela fonctionnera dans plus de cas.
from copy import deepcopy
from typing import TypeVar
Cls = TypeVar('Cls')
# This type hint is a dirty lie to make autocomplete and static
# analyzers give more useful results. Crazy the stuff you can do
# with python...
def copy_class(cls: Cls) -> Cls:
copy_cls = type(f'{cls.__name__}Copy', cls.__bases__, dict(cls.__dict__))
for name, attr in cls.__dict__.items():
try:
hash(attr)
except TypeError:
# Assume lack of __hash__ implies mutability. This is NOT
# a bullet proof assumption but good in many cases.
setattr(copy_cls, name, deepcopy(attr))
return copy_cls
def test_copy_class():
class A(object):
mutable_class_var = []
ACopy = copy_class(A)
a = A()
acopy = ACopy()
acopy.mutable_class_var.append(1)
assert a.mutable_class_var == []
assert A.mutable_class_var == []
assert ACopy.mutable_class_var == [1]
assert acopy.mutable_class_var == [1]
Je pense que vous comprenez mal le sens de variable statique ici. Partout où vous déclarez une variable en dehors d'une méthode et non sous la forme de self.some_thing
, la variable sera considérée comme la variable statique de la classe (comme votre variable ARG ici). Ainsi, chaque objet ( instance ) de la classe qui modifie une variable statique entraînera la modification de tous les autres objets de la même classe. Le deepcopy fait vraiment le travail ici.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.