Изменить экземпляр класса внутри метода экземпляра
Вопрос
Есть идеи, есть ли способ заставить следующий код работать
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
это что-то вроде следующего, которое безопасно использовать для более сложных объектов (например, моделей django, для горячей замены записи базы данных, на которую ссылается экземпляр)
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
Решение
self = Test(3)
повторно привязывает локальное имя self
, без каких-либо внешне наблюдаемых эффектов.
Назначение self.__dict__
(если вы не говорите об экземплярах с __slots__
или из классов с нетривиальными метаклассами) обычно нормально, как и self.__init__(3)
для повторной инициализации экземпляра.Однако я бы предпочел иметь конкретный метод self.restart(3)
который знает он вызывается на уже инициализированном экземпляре и делает все необходимое для удовлетворения этого конкретного и необычного случая.
Другие советы
Нет и нет.
Сказав это, вы может изменить сорт, но и этого не делайте.
Первый код работает, но он мало что делает, поскольку он просто заменяет объект с именем «self» в области действия Changeme().Имена Python не привязаны к значениям, они всегда относятся к своей области действия или пространству имен.
Чтобы сделать то, что вы хотите, вам понадобится доступ к имени вне класса, которое вы можете назначить изнутри него:
class Test:
def changeme(self):
global myclass
myclass = Test(3)
myclass = Test(2)
myclass.changeme()
print myclass # 3
По сути, это просто перезаписывает имя «myclass», чтобы оно указывало на новый экземпляр.Он не «перезаписывает» первый экземпляр, как вы думаете.Старый экземпляр все еще существует и будет удален для сбора мусора, если на него не будет сделана ссылка где-либо еще.