nicialização de membros da classe Python
Acabei de combater um bug no Python recentemente. Era um daqueles bichos novatos, mas me fez pensar nos mecanismos do Python (sou programador de C ++ há muito tempo, novo no Python). Vou apresentar o código do buggy e explicar o que fiz para corrigi-lo. Depois, tenho algumas perguntas ...
O cenário: eu tenho uma classe chamada A, que possui um membro de dados do dicionário, a seguir está seu código (isso é simplificação, é claro):
class A:
dict1={}
def add_stuff_to_1(self, k, v):
self.dict1[k]=v
def print_stuff(self):
print(self.dict1)
A classe que usa esse código é a classe B:
class B:
def do_something_with_a1(self):
a_instance = A()
a_instance.print_stuff()
a_instance.add_stuff_to_1('a', 1)
a_instance.add_stuff_to_1('b', 2)
a_instance.print_stuff()
def do_something_with_a2(self):
a_instance = A()
a_instance.print_stuff()
a_instance.add_stuff_to_1('c', 1)
a_instance.add_stuff_to_1('d', 2)
a_instance.print_stuff()
def do_something_with_a3(self):
a_instance = A()
a_instance.print_stuff()
a_instance.add_stuff_to_1('e', 1)
a_instance.add_stuff_to_1('f', 2)
a_instance.print_stuff()
def __init__(self):
self.do_something_with_a1()
print("---")
self.do_something_with_a2()
print("---")
self.do_something_with_a3()
Observe que todas as chamadas parado_something_with_aX()
inicializa uma nova instância "limpa" da classe A e imprime o dicionário antes e depois da adiçã
O bug (caso você ainda não tenha descoberto):
>>> b_instance = B()
{}
{'a': 1, 'b': 2}
---
{'a': 1, 'b': 2}
{'a': 1, 'c': 1, 'b': 2, 'd': 2}
---
{'a': 1, 'c': 1, 'b': 2, 'd': 2}
{'a': 1, 'c': 1, 'b': 2, 'e': 1, 'd': 2, 'f': 2}
Na segunda inicialização da classe A, os dicionários não estão vazios, mas começam com o conteúdo da última inicialização e assim por diante. Eu esperava que eles começassem "frescos".
O que resolve esse "bug" está adicionando obviamente:
self.dict1 = {}
No__init__
construtor da classe A. No entanto, isso me fez pensar:
EDIT: Após as respostas, agora entendo que declarando um membro de dados e não fazendo referência a ele no__init__
ou em outro lugar como self.dict1, estou praticamente definindo o que é chamado em C ++ / Java um membro de dados estático. Ao chamá-lo self.dict1, estou tornando-o "vinculado à instância".