Изменить экземпляр класса внутри метода экземпляра

StackOverflow https://stackoverflow.com/questions/2137772

Вопрос

Есть идеи, есть ли способ заставить следующий код работать

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», чтобы оно указывало на новый экземпляр.Он не «перезаписывает» первый экземпляр, как вы думаете.Старый экземпляр все еще существует и будет удален для сбора мусора, если на него не будет сделана ссылка где-либо еще.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top