deepcopy
de copy
no copia una clase:¿Cómo copiar una clase de python?
>>> class A(object):
>>> ARG = 1
>>> B = deepcopy(A)
>>> A().ARG
>>> 1
>>> B().ARG
>>> 1
>>> A.ARG = 2
>>> B().ARG
>>> 2
Es única manera?
B(A):
pass
deepcopy
de copy
no copia una clase:¿Cómo copiar una clase de python?
>>> class A(object):
>>> ARG = 1
>>> B = deepcopy(A)
>>> A().ARG
>>> 1
>>> B().ARG
>>> 1
>>> A.ARG = 2
>>> B().ARG
>>> 2
Es única manera?
B(A):
pass
En general, la herencia es el camino correcto, como ya han señalado los otros carteles.
Sin embargo, si realmente desea volver a crear el mismo tipo con un nombre diferente y sin herencia a continuación, puede hacerlo de esta manera:
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'
Hay que tener cuidado con los valores de los atributos 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]' (!)
¿El dictado de la clase copiada está vinculado al dictado de clase que se creó primero? – I159
@ I159: Eso depende de los valores en '__dict__'. Los atributos no mutables son buenos, pero los valores de atributo mutables (como listas) o los mecanismos de fondo de las nuevas clases de estilo (por ejemplo, los descriptores) probablemente te morderán. –
Esto funciona bien solo si al atributo 'x' se le asigna un tipo inmutable y no un tipo mutable, porque' dict (C .__ dict __) 'solo hace una copia superficial, no una copia profunda. – hynekcer
La forma correcta de "copia" de una clase, es decir, a medida que conjeturar, la herencia:
class B(A):
pass
También puede hacerlo usando 'type()', p. Ej. 'B = tipo (" B ", (A,), {})' – kindall
La herencia no hace lo que se requiere (dependencia de los valores ARG) a menos que se asigne también un valor a B.ARG. – hynekcer
@hynecker: ¿podría explicar a qué se refiere con eso? Creo que esto responde la pregunta del OP –
Si desea crear sólo otro ejemplo de la clase a continuación, sólo lo hacen:
>>> class A(object):
... ARG=1
...
>>> a = A()
>>> A().ARG
1
>>> b = A()
>>> b.ARG
1
>>> a.ARG=2
>>> b.ARG
1
Crear su propio constructor, y simplemente duplicar cómo se hizo su clase original:
class MyClass(object):
def __init__(self, **kw):
self.kw = kw
self.__dict__.update(kw)
def copy(self):
return MyClass(**self.kw)
Sin embargo, intentaría evitar la necesidad de copiar objetos en primer lugar.
sidenote: También podría ser capaz de salirse con la suya haciendo:
B = deepcopy(A)
B.__dict__ = deepcopy(A.__dict__)
pero esto es probablemente muy, muy mal y no debe hacer esto. edición: AttributeError: 'dictproxy' object has no attribute 'update'
realidad de acuerdo con la OP
En realidad 'AttributeError: 'dictproxy' objeto no tiene atributo 'update'' – I159
Se podría utilizar una función de fábrica:
def get_A():
class A(object):
ARG = 1
return A
A = get_A()
B = get_A()
Creo que usted no entiende el significado de la variable estática aquí. Cada vez que declare una variable fuera de un método y no en la forma de self.some_thing
, la variable se considerará como variable estática de la clase (como su variable ARG aquí). Por lo tanto, cada objeto (instancia) de la Clase que cambia una variable estática causará el cambio de todos los demás objetos en la misma Clase. La copia profunda realmente hace el trabajo aquí.
Nota: la pregunta correcta sería "Cómo copiar la instancia de la clase python u objeto python", no la clase python en sí. –
En realidad, Pavel, parece que I159 realmente está tratando de copiar la clase en sí –
Sin mencionar que en Python, una clase es solo otro objeto, pero con un extraño atributo '__dict__'. –