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

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

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

3 ответов


self = Test(3) повторно связывает локальное имя self, без внешних наблюдаемых эффектов.

назначение self.__dict__ (Если вы не говорите об экземплярах с __slots__ или из классов с нетривиальными метаклассами) обычно в порядке, и так же self.__init__(3) для повторной инициализации экземпляра. Однако я бы предпочел иметь конкретный метод self.restart(3), который знает он вызывается на уже инициализированном экземпляре и делает все необходимое для удовлетворения этого конкретного и исключительный случай.


нет, и нет.

сказав Это, ты can изменить класс, но и этого не делай.


прежний код работает, за исключением того, что он не будет много делать, поскольку он просто заменяет объект с именем "self" в области changeme(). Имена Python не заблокированы для значений, они всегда относительно их области или пространства имен.

чтобы сделать то, что вы хотите, вам нужно иметь доступ к имени вне класса, которому вы можете назначить его изнутри:

class Test:
  def changeme(self):
    global myclass
    myclass = Test(3)

myclass = Test(2)
myclass.changeme()
print myclass # 3

это в основном просто перезаписывает имя "myclass", чтобы указать на новый экземпляр. Он не " перезаписывает" первый случай, как вы можете подумать. Старый экземпляр все еще живет и будет собирать мусор, если на него не ссылаться в другом месте.