Python __get / set / delattr__, assegnazione ordinaria contro __setattr__, __dict__ vs dir ()

1

Ho alcune altre domande relative a Python OOP:

  • Che cosa fanno esattamente questi attributi: __get/set/delattr__ ?

  • Perché non utilizzare solo Myclass.NewAttr = value anziché __setattr__ ?

  • Perché Python usa __dict__ ? Mantiene comunque gli attributi alla fine di dir ().

posta Adi Gal 10.03.2016 - 12:59
fonte

1 risposta

2

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.

    
risposta data 10.03.2016 - 13:46
fonte

Leggi altre domande sui tag