2015-12-31 26 views
5

Capisco che in python, ogni volta che si accede a una variabile di classe/istanza, chiamerà il metodo __getattribute__ per ottenere il risultato. Tuttavia, posso anche usare direttamente obj.__dict__['x'] e ottenere quello che voglio.Differenza tra __getattribute__ e obj .__ dict __ ['x'] in python?

Sono un po 'confuso su quale sia la differenza? Anche quando uso getattr(obj, name), si chiama __getattribute__ o obj.__dict__[name] internamente?

Grazie in anticipo.

+0

http://stackoverflow.com/questions/3278077/difference-between-getattr-vs-getattribute dovrebbe chiarire il tuo dubbio. –

+0

@AashishP grazie per il commento. Ma quel post spiega la differenza tra '__getattr__' e' __getattribute__'. Sembra che 'getattr' abbia poco a che fare con' __getattr__', quindi stai implicando che 'getattr' sia effettivamente uguale a' obj .__ dict __ [nome] '? – cizixs

+0

Sì, giusto. Ho provato a scavare il codice sorgente di CPython ed ecco cosa ho trovato, in linguaggio semplice, http://stackoverflow.com/questions/24863787/python-the-getattribute-method-and-descriptors –

risposta

1

__getattribute__() metodo è per l'elaborazione di attributo di livello inferiore.

L'implementazione predefinita tenta di trovare il nome nello __dict__ interno (o __slots__). Se l'attributo non viene trovato, chiama __getattr__().

UPDATE (come nel commento):

Essi sono modi diversi per trovare gli attributi nel modello di dati Python. Sono metodi interni progettati per rientrare correttamente in qualsiasi situazione possibile. Un indizio: "Il macchinario è in object.__getattribute__() che trasforma b.x in type(b).__dict__['x'].__get__(b, type(b))." da docs.python.org/3/howto/descriptor.html

+0

Significa che "__getattribute__" chiamerà try find attribute in "__dict__' e farà più cose? In altre parole: '__getattribute__' è un superset del metodo' __dict__'. – cizixs

+0

Sono diversi modi per trovare gli attributi nel modello di dati Python. Sono metodi interni progettati per rientrare correttamente in qualsiasi situazione possibile. Un indizio: "Il meccanismo è in' oggetto .__ getattribute __() 'che trasforma' b.x' in 'tipo (b) .__ dict __ ['x'] .__ get __ (b, type (b))'. " da https://docs.python.org/3/howto/descriptor.html – tuned

0

Non tutti gli oggetti python hanno un dizionario in cui sono memorizzati gli attributi, ci sono slot, proprietà e attributi, che vengono calcolati, se necessario. È anche possibile sovrascrivere __getattribute__ e __getattr__. L'accesso agli attributi è più complicato di una semplice ricerca nel dizionario. Quindi il modo normale per accedere attributo è da

obj.x 

wenn avete una variabile con nome di attributo:

getattr(obj, name) 

Normalmente non dovrebbe usare gli attributi interni __xxx__.

+0

Grazie per il chiarimento. Ho letto da qualche parte che quando uso 'obj.x', sarà' __getattribute__', se non viene trovato, verrà chiamato '__getattr__'. Dov'è la variabile interna '__dict__'? Se viene utilizzato quando accedo a un attributo di istanza e non si consiglia di utilizzarlo direttamente, qual è il punto? – cizixs

0

Gli attributi in __dict__ sono solo un sottoinsieme di tutti gli attributi di un oggetto.

Considerate questa classe:

class C: 
    ac = "+AC+" 
    def __init__(self): 
     self.ab = "+AB+" 

    def show(self): 
     pass 

Un'istanza ic = C() di questa classe avranno attributi 'ab', 'ac' e 'show' (e pochi altri). Lo __gettattribute__ li troverà tutti, ma solo il valore "ab" è memorizzato nello ic.__dict__. Gli altri due possono essere trovati in C.__dict__.

Problemi correlati