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