Changer instance de classe à l'intérieur d'une méthode d'instance
Question
Toute idée s'il y a un moyen de rendre le code suivant pour travailler
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
est quelque chose comme sûr à utiliser pour des objets plus complexes (comme les modèles de django, de remplacer à chaud l'entrée db l'instance fait référence)
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
La solution
self = Test(3)
est réappairant le self
nom local, sans effets observables à l'extérieur.
Attribution self.__dict__
(à moins que vous parlez des cas avec __slots__
ou des classes avec métaclasses non trivial) est généralement OK, et est donc self.__init__(3)
de ré-initialiser l'instance. Cependant, je préfère avoir une méthode self.restart(3)
spécifique sait il est appelé sur une instance déjà initialisé et fait tout ce qui est nécessaire pour répondre à ce cas particulier et inhabituel.
Autres conseils
Non et non.
Ceci étant dit, vous peut modifier classe , mais ne le font pas non plus.
L'ancien code fonctionne, sauf qu'il ne fera pas beaucoup, car il remplace simplement l'objet nommé « soi » dans le cadre de changeme (). Les noms de Python ne sont pas verrouillés à des valeurs, ils sont toujours par rapport à leur portée ou de l'espace de noms.
Pour faire ce que vous voulez, vous aurez besoin d'avoir accès à un nom en dehors de la classe, que vous pouvez affecter à l'intérieur il:
class Test:
def changeme(self):
global myclass
myclass = Test(3)
myclass = Test(2)
myclass.changeme()
print myclass # 3
Cette fondamentalement juste le remplace le nom « MyClass » pour pointer vers la nouvelle instance. Il n'a pas « écraser » la première instance comme vous pourriez penser. L'ancienne instance vit encore, et sera garbage collection À moins d'indication ailleurs.