2010-04-14 8 views
11
class attrdict(dict): 
    def __init__(self, *args, **kwargs): 
     dict.__init__(self, *args, **kwargs) 
     self.__dict__ = self 

a = attrdict(x=1, y=2) 
print a.x, a.y 

b = attrdict() 
b.x, b.y = 1, 2 
print b.x, b.y 

Qualcuno potrebbe spiegare le prime quattro righe in parole? Leggo su classi e metodi. Ma qui sembra molto confuso.classe, dict, self, init, args?

+0

questo è un buon modo per perdere memoria. Vedi http://bugs.python.org/issue1469629 per una spiegazione e un'alternativa migliore. –

risposta

5

Non si stanno utilizzando gli argomenti posizionali nell'esempio. Quindi il codice di riferimento è:

class attrdict(dict): 
    def __init__(self, **kwargs): 
     dict.__init__(self, **kwargs) 
     self.__dict__ = self 

Nella prima riga si definisce classe attrdict come una sottoclasse di dict. Nella seconda riga si definisce la funzione che inizializzerà automaticamente l'istanza. Passi gli argomenti delle parole chiave (**kargs) a questa funzione. Quando si crea un'istanza a:

a = attrdict(x=1, y=2) 

in realtà si sta chiamando

attrdict.__init__(a, {'x':1, 'y':2}) 

dict esempio di inizializzazione di base è fatto da inizializzare l'dict superclasse incorporato. Questo viene fatto nella terza riga passando i parametri ricevuti in attrdict.__init__. Così,

dict.__init__(self,{'x':1, 'y':2}) 

rende self (l'istanza a) un dizionario:

self == {'x':1, 'y':2} 

La cosa bella si verifica nell'ultima riga: Ogni istanza ha un dizionario che tiene i suoi attributi. Questo è self.__dict__ (ad es.a.__dict__).

Ad esempio, se

a.__dict__ = {'x':1, 'y':2} 

possiamo scrivere a.x o a.y e ottenere i valori 1 o 2, rispettivamente.

Quindi, questo è quello che fa la linea 4:

self.__dict__ = self 

è equivalente a:

a.__dict__ = a where a = {'x':1, 'y':2} 

Poi posso chiamare a.x e a.y.

La speranza non è troppo caotica.

+0

migliore di quello accettato. – Musaffa

4

Ecco un buon articolo che spiega __dict__:

The Dynamic dict

La classe attrdict sfrutta che ereditando da un dizionario e quindi impostando dell'oggetto __dict__ a quel dizionario. Pertanto, qualsiasi accesso agli attributi si verifica nei confronti del dizionario principale (ad esempio la classe dict da cui eredita).

Il resto dell'articolo è abbastanza buono anche per gli oggetti Python comprensione:

Python Attributes and Methods

7

mio colpo ad una spiegazione riga per riga:

class attrdict(dict): 

Questa linea dichiara una classe attrdict come sottoclasse della classe dict incorporata.

def __init__(self, *args, **kwargs): 
    dict.__init__(self, *args, **kwargs) 

Questo è il metodo standard __init__. La chiamata a dict.__init__(...) consiste nell'utilizzare il metodo super classe '(in questo caso, dict) (__init__).

La riga finale, self.__dict__ = self rende così possibile accedere agli argomenti delle parole chiave (kwarg) che si passano al metodo __init__ come attributi, ad esempio, a.x, a.y nel codice riportato di seguito.

Spero che questo aiuti a chiarire la tua confusione.

+0

È necessario correggere '__init__'. Metti i reticoli intorno a loro e sembreranno il mio '__init__'. –

+0

Questo aiuto così tanto. Grazie! – kame