2010-04-14 29 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 

¿Alguien podría explicar las primeras cuatro líneas en palabras? Leí sobre clases y métodos. Pero aquí parece muy confuso.clase, dict, self, init, args?

+0

esta es una buena manera de perder memoria. Consulte http://bugs.python.org/issue1469629 para obtener una explicación y una mejor alternativa. –

Respuesta

5

No está utilizando argumentos posicionales en su ejemplo. Por lo que el código en cuestión es:

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

En la primera línea que define la clase attrdict como una subclase de dict. En la segunda línea, define la función que iniciará automáticamente su instancia. Pasa los argumentos de palabra clave (**kargs) a esta función. Al crear una instancia a:

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

en realidad se está llamando

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

dict instancia central de inicialización se realiza mediante la inicialización de la superclase dict incorporado. Esto se hace en la tercera línea pasando los parámetros recibidos en attrdict.__init__. Por lo tanto,

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

hace self (la instancia a) un diccionario:

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

Lo bueno que ocurre en la última línea: Cada instancia tiene un diccionario de la celebración de sus atributos. Esto es self.__dict__ (es decira.__dict__).

Por ejemplo, si

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

podríamos escribir a.x o a.y y obtener valores de 1 ó 2, respectivamente.

Por lo tanto, esto es lo que hace la línea 4:

self.__dict__ = self 

es equivalente a:

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

Entonces puedo llamar a.x y a.y.

Espero que no sea demasiado complicado.

+0

mejor que el aceptado. – Musaffa

4

He aquí un buen artículo que explica __dict__:

The Dynamic dict

La clase attrdict explota esa heredando de un diccionario, y luego poner el objeto de __dict__ a ese diccionario. De modo que cualquier acceso de atributo se produce contra el diccionario principal (es decir, la clase dict de la que hereda).

El resto del artículo es bastante bueno también para los objetos de Python comprensión:

Python Attributes and Methods

7

Mi tiro en una explicación línea por línea:

class attrdict(dict): 

Esta línea declara una clase attrdict como una subclase de la clase dict incorporada.

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

Este es su método estándar __init__. La llamada al dict.__init__(...) consiste en utilizar el método de la clase '(en este caso, dict) constructor (__init__).

La línea final, self.__dict__ = self lo hace para que los argumentos de palabra clave (kwargs) que pasa al método __init__ puedan accederse como atributos, es decir, a.x, a.y en el código siguiente.

Espero que esto ayude a aclarar su confusión.

+0

Necesita reparar el '__init__'. Coloque palos alrededor, y se verán como mi '__init__'. –

+0

Esto ayuda mucho. ¡Gracias! – kame

Cuestiones relacionadas