Embora a resposta aceita esteja correta, eu gostaria de adicionar uma pequena descrição.
Vamos fazer um pequeno exercício
Antes de tudo, defina uma classe da seguinte maneira:
class A:
temp = 'Skyharbor'
def __init__(self, x):
self.x = x
def change(self, y):
self.temp = y
Então o que temos aqui?
- Temos uma classe muito simples que tem um atributo
temp
que é uma string
- Um
__init__
método que defineself.x
- Um método de mudança define
self.temp
Bem direto até agora, sim? Agora vamos começar a brincar com essa classe. Vamos inicializar esta classe primeiro:
a = A('Tesseract')
Agora faça o seguinte:
>>> print(a.temp)
Skyharbor
>>> print(A.temp)
Skyharbor
Bem, a.temp
funcionou como esperado, mas como diabos A.temp
funcionou? Bem, funcionou porque temp é um atributo de classe. Tudo em python é um objeto. Aqui A também é um objeto de classe type
. Portanto, o atributo temp é um atributo mantido pela A
classe e se você alterar o valor de temp através A
(e não através de uma instância de a
), o valor alterado será refletido em toda a instância da A
classe. Vamos em frente e faça isso:
>>> A.temp = 'Monuments'
>>> print(A.temp)
Monuments
>>> print(a.temp)
Monuments
Interessante, não é? E note que id(a.temp)
e id(A.temp)
ainda são os mesmos .
Qualquer objeto Python recebe automaticamente um __dict__
atributo, que contém sua lista de atributos. Vamos investigar o que esse dicionário contém para nossos objetos de exemplo:
>>> print(A.__dict__)
{
'change': <function change at 0x7f5e26fee6e0>,
'__module__': '__main__',
'__init__': <function __init__ at 0x7f5e26fee668>,
'temp': 'Monuments',
'__doc__': None
}
>>> print(a.__dict__)
{x: 'Tesseract'}
Observe que o temp
atributo é listado entre A
os atributos da classe, enquanto x
é listado para a instância.
Então, como é que obtemos um valor definido a.temp
se ele nem está listado para a instância a
? Bem, essa é a mágica do __getattribute__()
método. No Python, a sintaxe pontilhada invoca automaticamente esse método; portanto, quando escrevemos a.temp
, o Python é executado a.__getattribute__('temp')
. Esse método executa a ação de pesquisa de atributo, ou seja, localiza o valor do atributo procurando em lugares diferentes.
A implementação padrão de __getattribute__()
pesquisas primeiro no dicionário interno ( dict ) de um objeto, depois no tipo do objeto em si. Nesse caso, a.__getattribute__('temp')
executa primeiro a.__dict__['temp']
e depoisa.__class__.__dict__['temp']
Ok, agora vamos usar o nosso change
método:
>>> a.change('Intervals')
>>> print(a.temp)
Intervals
>>> print(A.temp)
Monuments
Bem, agora que usamos self
, print(a.temp)
nos dá um valor diferente de print(A.temp)
.
Agora, se compararmos id(a.temp)
e id(A.temp)
, eles serão diferentes.
list
como um nome de atributo.list
é uma função embutida para construir uma nova lista. Você deve escrever classes de nome com letra maiúscula.