Sebbene la risposta accettata sia corretta, vorrei aggiungere una breve descrizione.
Facciamo un piccolo esercizio
prima di tutto definire una classe come segue:
class A:
temp = 'Skyharbor'
def __init__(self, x):
self.x = x
def change(self, y):
self.temp = y
Allora, cosa abbiamo qui?
- Abbiamo una classe molto semplice che ha un attributo
temp
che è una stringa
- Un
__init__
metodo che impostaself.x
- Viene impostato un metodo di modifica
self.temp
Abbastanza semplice finora, sì? Ora iniziamo a giocare con questa classe. Inizializziamo prima questa classe:
a = A('Tesseract')
Ora procedi come segue:
>>> print(a.temp)
Skyharbor
>>> print(A.temp)
Skyharbor
Bene, ha a.temp
funzionato come previsto, ma come diavolo ha A.temp
funzionato? Bene ha funzionato perché temp è un attributo di classe. Tutto in Python è un oggetto. Qui A è anche un oggetto di classe type
. Pertanto, l'attributo temp è un attributo detenuto dalla A
classe e se si modifica il valore di temp tramite A
(e non attraverso un'istanza di a
), il valore modificato si rifletterà in tutte le istanze della A
classe. Andiamo avanti e facciamo questo:
>>> A.temp = 'Monuments'
>>> print(A.temp)
Monuments
>>> print(a.temp)
Monuments
Interessante vero? E notare che id(a.temp)
e id(A.temp)
sono ancora la stessa .
A qualsiasi oggetto Python viene assegnato automaticamente un __dict__
attributo, che contiene il suo elenco di attributi. Analizziamo cosa contiene questo dizionario per i nostri oggetti di esempio:
>>> print(A.__dict__)
{
'change': <function change at 0x7f5e26fee6e0>,
'__module__': '__main__',
'__init__': <function __init__ at 0x7f5e26fee668>,
'temp': 'Monuments',
'__doc__': None
}
>>> print(a.__dict__)
{x: 'Tesseract'}
Nota che l' temp
attributo è elencato tra A
gli attributi della classe mentre x
è elencato per l'istanza.
Quindi, come mai otteniamo un valore definito a.temp
se non è nemmeno elencato per l'istanza a
. Bene, questa è la magia del __getattribute__()
metodo. In Python la sintassi punteggiata invoca automaticamente questo metodo, quindi quando scriviamo a.temp
, Python viene eseguito a.__getattribute__('temp')
. Tale metodo esegue l'azione di ricerca dell'attributo, ovvero trova il valore dell'attributo guardando in luoghi diversi.
L'implementazione standard delle __getattribute__()
ricerche prima il dizionario interno ( dict ) di un oggetto, quindi il tipo di oggetto stesso. In questo caso a.__getattribute__('temp')
viene eseguito prima a.__dict__['temp']
e poia.__class__.__dict__['temp']
Bene ora usiamo il nostro change
metodo:
>>> a.change('Intervals')
>>> print(a.temp)
Intervals
>>> print(A.temp)
Monuments
Bene, ora che abbiamo usato self
, print(a.temp)
ci dà un valore diverso daprint(A.temp)
.
Ora se confrontiamo id(a.temp)
e id(A.temp)
, saranno diversi.
list
come nome di attributo.list
è una funzione integrata per costruire un nuovo elenco. Dovresti scrivere le classi di nomi con la lettera maiuscola.