Cambio instancia de clase dentro de un método de instancia
Pregunta
Cualquier idea si hay una manera de hacer que el código siguiente para el trabajo
class Test(object):
def __init__(self, var):
self.var = var
def changeme(self):
self = Test(3)
t = Test(1)
assert t.var == 1
t.changeme()
assert t.var == 3
es algo así como la siguiente seguro de usar para objetos más complejos (como django modelos, para intercambio en caliente de la entrada db la instancia se refería a)
class Test(object):
def __init__(self, var):
self.var = var
def changeme(self):
new_instance = Test(3)
self.__dict__ = new_instance.__dict__
t = Test(1)
assert t.var == 1
t.changeme()
assert t.var == 3
Solución
self = Test(3)
es re-unión el nombre self
locales, sin efectos observables externamente.
Asignación self.__dict__
(a menos que estés hablando de casos con __slots__
o de clases con metaclases no triviales) es por lo general bien, y así es self.__init__(3)
para reiniciar la instancia. Sin embargo yo prefiero tener un método específico self.restart(3)
que sabe que está siendo llamado a una instancia ya inicializado y hace lo que se necesita para hacer frente a ese concreto e inusual.
Otros consejos
No, y no.
Una vez dicho esto, que puede cambiar el class , pero no hacer que tampoco.
Los trabajos anteriores de código, excepto que no servirá de mucho, ya que sólo se reemplaza el objeto denominado 'auto' dentro del ámbito de changeme (). nombres de Python no están cerradas a los valores, que están siempre en relación con su ámbito o espacio de nombres.
Para hacer lo que quiera que había necesidad de tener acceso a un nombre fuera de la clase, lo que podría asignar a partir de dentro de ella:
class Test:
def changeme(self):
global myclass
myclass = Test(3)
myclass = Test(2)
myclass.changeme()
print myclass # 3
Esto, básicamente, sólo sobrescribe el nombre de 'miclase' a punto de la nueva instancia. No "sobrescribir" el primer ejemplo de que se puede pensar. La instancia antigua aún vive, y será el recolector de basura a menos que se hace referencia en otro lugar.