Ändern Klasseninstanz innerhalb einer Instanzmethode
Frage
Jede Idee, wenn es einen Weg, um den folgenden Code an die Arbeit machen
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
ist so etwas wie die sichere folgenden für komplexere Objekte zu verwenden (wie Django Modelle, auf den Hot-Swap-db Eintrag die Instanz bezieht)
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
Lösung
self = Test(3)
ist re-binding den lokalen Namen self
, ohne von außen beobachtbaren Effekte.
self.__dict__
zuordnen (es sei denn, Sie sprechen Instanzen mit __slots__
oder von Klassen mit nicht-trivialer metaclasses) ist in der Regel in Ordnung, und so ist self.__init__(3)
auf die Instanz neu zu initialisieren. Allerdings würde ich es vorziehen, eine spezifische Methode self.restart(3)
zu haben, die weiß ist es auf eine bereits initialisierte Instanz aufgerufen wird, und tut, was für diesen speziellen und ungewöhnlichen Fall gerecht zu werden gebraucht wird.
Andere Tipps
Nein, und Nr.
Having said that, Sie können ändern Sie die Klasse , aber tun Sie nicht, dass entweder.
Der ehemalige Code funktioniert, außer es wird nicht viel tun, da es nur das Objekt ersetzt namens ‚Selbst‘ im Rahmen von changeme (). Python-Namen werden auf Werte nicht gesperrt ist, sind sie ihren Umfang oder Namensraum immer relativ.
Zu tun, was Sie wollen, müssen Sie Zugriff auf einen Namen außerhalb der Klasse haben, die Sie von innen zuweisen konnten:
class Test:
def changeme(self):
global myclass
myclass = Test(3)
myclass = Test(2)
myclass.changeme()
print myclass # 3
Diese im Grunde überschreibt nur den Namen ‚myclass‘ zu Punkt auf die neue Instanz. Es ist nicht „überschreiben“ die erste Instanz, wie Sie vielleicht denken. Die alte Instanz noch lebt, und wird Müll, es sei denn an anderer Stelle verwiesen gesammelt werden.