Alterar a instância da classe dentro de um método de instância
Pergunta
Alguma idéia se houver uma maneira de fazer o seguinte código para funcionar
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
é algo como o seguinte a seguir para obter objetos mais complexos (como os modelos Django, para trocar a quente a entrada do banco de dados à qual a instância está se referindo)
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
Solução
self = Test(3)
está re-vinculando o nome local self
, sem efeitos externamente observáveis.
Atribuição self.__dict__
(a menos que você esteja falando sobre instâncias com __slots__
ou de aulas com metaclasses não triviais) geralmente é bom, e também é self.__init__(3)
Para reinicializar a instância. No entanto, eu prefiro ter um método específico self.restart(3)
que sabe Ele está sendo chamado em uma instância já inicializada e faz o que for necessário para atender a esse caso específico e incomum.
Outras dicas
Não, e não.
Dito isto, você posso mudar o classe, mas também não faça isso.
O código anterior funciona, exceto que não fará muito, visto que apenas substitui o objeto chamado 'Self' dentro do escopo de ChangeMe (). Os nomes do Python não estão bloqueados nos valores, eles são sempre relativos ao seu escopo ou namespace.
Para fazer o que quiser, você precisaria ter acesso a um nome fora da aula, para o qual você poderia atribuir de dentro dele:
class Test:
def changeme(self):
global myclass
myclass = Test(3)
myclass = Test(2)
myclass.changeme()
print myclass # 3
Isso basicamente apenas substitui o nome 'MyClass' para apontar para a nova instância. Não "substitui" a primeira instância como você imagina. A antiga instância ainda vive e será coletada de lixo, a menos que se refere a outro lugar.