Metodi descrittore Python
What does these attributes do exactly: __get/set/delattr__
?
Questo è difficile da iniziare, e abbastanza avanzato - la maggior parte dei programmatori Python non ha bisogno di sapere questo, semplicemente memorizzano come gli oggetti (principalmente metodi e decoratori di metodi) che usano questo lavoro.
Sono metodi speciali che rendono un oggetto un "descrittore". Se questo oggetto viene cercato attraverso un altro oggetto, viene richiamato. Sono come funzionano property
, classmethod
e staticmethod
. Sono anche le modalità con cui le normali funzioni possono diventare metodi vincolati.
Ad esempio:
>>> class Foo:
... def __init__(self, bar):
... self.bar = bar
... @property
... def baz(self):
... return bar * 2
>>> Foo.__init__.__get__
<method-wrapper '__get__' of function object at 0x7f1c1d23b158>
La __get__
è invocata quando fai Foo.__init__
(che è invocato da Foo()
). Lega l'istanza al primo argomento (di solito lo chiamiamo self
) al metodo sulla ricerca tratteggiata.
>>> Foo.baz.__set__
<method-wrapper '__set__' of property object at 0x7f1c1d225e58>
Quel metodo __set__
è quello che viene invocato quando proviamo ad assegnare il nome baz
alla ricerca puntata sul lato sinistro del compito (dato che non abbiamo definito un setter, baz è di sola lettura ) e tale metodo solleva il seguente errore:
>>> f = Foo('bar')
>>> f.baz = 'boink'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
Ho scritto una risposta canonica e molto approfondita su questo argomento su StackOverflow qui .
Assegnazione rispetto a __setattr__
(rispetto a setattr
)
Why not use just Myclass.NewAttr = value
instead of __setattr__
?
Sì, dovresti farlo. __setattr__
deve essere utilizzato solo quando si implementa un comportamento speciale su un oggetto.
C'è anche una funzione incorporata chiamata setattr
- funziona se devi determina a livello di codice il nome a cui stai assegnando e non può semplicemente utilizzare un nome statico nel tuo codice.
__dict__
contro dir
Why does Python use __dict__
? It keeps the attributes in the end of dir()
anyway.
In realtà, gli attributi (membri dei dati) sono memorizzati nel dizionario - dir()
guarda solo i loro nomi lì sopra.