2010-05-27 38 views
13

tengo una pregunta sobre el atributo de clase en python.atributo de clase python

class base : 
    def __init__ (self): 
     pass 
    derived_val = 1 

t1 = base() 
t2 = base() 

t2.derived_val +=1 
t2.__class__.derived_val +=2 
print t2.derived_val    # its value is 2 
print t2.__class__.derived_val # its value is 3 

Los resultados son diferentes. También uso la función id() para encontrar t2.derived_val y t2. clase .derived_val tienen una dirección de memoria diferente. Mi problema es derivado_val es el atributo de clase. ¿Por qué es diferente en el ejemplo anterior? ¿Es porque la instancia de clase copia su propio derived_val al lado del atributo de clase?

Respuesta

34

Hay atributos de clase y atributos de instancia. Cuando dice

class base : 
    derived_val = 1 

va a definir un atributo de clase. derived_val se convierte en una clave en base.__dict__.

t2=base() 
print(base.__dict__) 
# {'derived_val': 1, '__module__': '__main__', '__doc__': None} 
print(t2.__dict__) 
# {} 

Cuando dice t2.derived_val Python trata de encontrar 'derived_val' en t2.__dict__. Como no está allí, se ve si hay una clave 'derived_val' en cualquiera de las clases base de t2.

print(t2.derived_val) 
print(t2.__dict__) 
# 1 
# {} 

Pero cuando se asigna un valor a t2.derived_val, que ahora está agregando una instancia de atributos a t2. Se agrega una clave derived_val al t2.__dict__.

t2.derived_val = t2.derived_val+1 
print(t2.derived_val) 
print(t2.__dict__) 
# 2 
# {'derived_val': 2} 

Tenga en cuenta que en este punto, hay dos derived_val atributos, pero sólo el atributo de instancia es de fácil acceso. El atributo de clase solo se puede acceder a través de la referencia base.derived_val o el acceso directo a la clase dict base.__dict__.

2

Échale un vistazo a here y here. El atributo __class__ es la clase a la que pertenece el objeto. Entonces en su ejemplo, la situación es similar a las variables estáticas. El t2.__class__.derived_val se refiere a la variable que pertenece a la clase, no a la variable que pertenece a t2.

1

Otra forma (tal vez una más concisa) Para demostrar esto:

class A(): 
    a1 = [] 
x = A() 
y = A() 
x.a1.append("test") 
x.a1, y.a1 
(['test'], ['test']) 

class B(): 
    b1 = None 
    def __init__(self): 
     self.b1 = list() 
r = B() 
s = B() 
r.b1.append("test") 
r.b1, s.b1 
(["test"], []) 
Cuestiones relacionadas