Uma breve nota da série "Você foi avisado".
Mudar de linguagens de programação clássicas para Python traz muitas surpresas.
Leia a documentação:
De um modo geral, as variáveis de instância são para dados exclusivos de cada instância e as variáveis de classe são para atributos e métodos compartilhados por todas as instâncias da classe
Vamos tentar brincar
class Vessel:
Crie dois objetos, verifique os valores de
todos os atributos:
Iowa = Vessel("Iowa") Drum=Vessel("Drum") printAttr(Iowa, Drum) >>name=Iowa vtype=boat __class__.vtype=boat >>name=Drum vtype=boat __class__.vtype=boat
Até agora, como esperado.
Vamos tentar mudar o vtype: isso pode ser feito de duas maneiras, que são essencialmente apenas uma sintaxe diferente da mesma
Vessel.vtype = "USS boat" printAttr(Iowa, Drum) >>name=Iowa vtype=USS boat __class__.vtype=USS boat >>name=Drum vtype=USS boat __class__.vtype=USS boat Iowa.__class__.vtype = 'USS WW2 Boat' printAttr(Iowa, Drum) >>name=Iowa vtype=USS WW2 Boat __class__.vtype=USS WW2 Boat >>name=Drum vtype=USS WW2 Boat __class__.vtype=USS WW2 Boat
E, novamente, tudo está em ordem.
Agora vamos tentar fazer o mesmo através do atributo do objeto.
Drum.vtype = 'submarine' printAttr(Iowa, Drum) >>name=Iowa vtype=USS WW2 Boat __class__.vtype=USS WW2 Boat >>name=Drum vtype=submarine __class__.vtype=USS WW2 Boat
E aqui está a primeira surpresa: apesar do fato de que vtype é um atributo de uma classe, de repente ele se torna um atributo de um objeto.
Verifique:
Vessel.vtype = "NAVY Museum" >>name=Iowa vtype=NAVY Museum __class__.vtype=NAVY Museum >>name=Drum vtype=submarine __class__.vtype=NAVY Museum
e se ...
del Drum.vtype >>name=Iowa vtype=NAVY Museum __class__.vtype=NAVY Museum >>name=Drum vtype=NAVY Museum __class__.vtype=NAVY Museum
E novamente um atributo de classe.
A expressão a seguir não passa mais
del Drum.vtype printAttr(Iowa, Drum) del Drum.vtype AttributeError: vtype
E o último exemplo que emula a classe substitui e remove o atributo vtype.
Drum.vtype = 'submarine' del Vessel.vtype printAttr(Iowa, Drum) >>name=Iowa >>name=Drum vtype=submarine
Se você começar a lidar com o espaço para nome, esse comportamento se tornará compreensível.
No entanto, para programadores que trabalharam anteriormente com linguagens normais, isso pelo menos parece estranho. E se falamos de grandes projetos apoiados por várias gerações de desenvolvedores, isso pode resultar em falha de prazos, etc.
Levando em conta o conceito de Python de que tudo está aberto a todos, por que não acessar os atributos "legais" somente por meio de __class__ ou de seu análogo. Na minha opinião, isso de alguma forma protegeria contra surpresas e me fez pensar 10 vezes antes de atribuir algo aos atributos de classe no nível do objeto.
Atualização: Text PrintAttr
def printAttr(*o): for a in o: print(a)