2010-05-27 17 views
13

Ho una domanda sull'attributo di classe in python.attributo della classe 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 

I risultati sono diversi. Uso anche la funzione id() per trovare t2.derived_val e t2. class .derived_val hanno un diverso indirizzo di memoria. Il mio problema è derived_val è l'attributo di classe. Perché è diverso nell'esempio sopra? È perché l'istanza della classe copia il proprio valore derivato accanto all'attributo class?

risposta

34

ci sono attributi di classe e gli attributi di istanza. Quando si dice

class base : 
    derived_val = 1 

si sta definendo un attributo di classe. derived_val diventa una chiave in base.__dict__.

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

Quando si dice t2.derived_val Python cerca di trovare 'derived_val' in t2.__dict__. Poiché non è lì, sembra che ci sia una chiave 'derived_val' in una qualsiasi delle classi base di t2.

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

Ma quando si assegna un valore a t2.derived_val, si è ora aggiunta un'istanza attributo t2. Una chiave derived_val viene aggiunta a t2.__dict__.

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

noti che, a questo punto, ci sono due derived_val attributi, ma solo l'attributo istanza è facilmente accessibile. L'attributo class diventa accessibile solo attraverso il riferimento base.derived_val o l'accesso diretto alla classe dict base.__dict__.

2

Check it out here e here.

L'attributo __class__ è la classe a cui appartiene l'oggetto. Quindi, nel tuo esempio, la situazione è simile alle variabili statiche. Il t2.__class__.derived_val si riferisce alla variabile che appartiene alla classe, non alla variabile che appartiene a t2.

1

Un altro modo (forse una più conciso) per dimostrare questo:

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"], []) 
Problemi correlati