2010-05-27 2 views
13

У меня возник вопрос о атрибуте класса в python.атрибут класса 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 

Результаты разные. Я также использую функцию id() для поиска t2.derived_val и t2. класс .derived_val иметь другой адрес памяти. Моя проблема является производным_value атрибутом класса. Почему в приведенном выше примере это отличается? Это потому, что экземпляр класса копирует свой собственный производный_val рядом с атрибутом класса?

ответ

34

Есть атрибуты класса и атрибуты экземпляра. Когда вы говорите

class base : 
    derived_val = 1 

Вы определяете атрибут класса. derived_val становится ключом в base.__dict__.

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

Когда вы говорите, t2.derived_val Python пытается найти 'derived_val' в t2.__dict__. Так как его нет, он выглядит, если есть 'derived_val' ключ в любом из базовых классов t2.

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

Но когда вы присваиваете значение t2.derived_val, вы теперь добавления экземпляра атрибута t2. К t2.__dict__ добавляется ключ derived_val.

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

Обратите внимание, что на данный момент, есть два derived_val атрибутов, но только атрибут экземпляра легко доступен. Атрибут класса становится доступным только путем ссылки base.derived_val или прямого доступа к классу dict base.__dict__.

2

Отметьте here и here.

Атрибут __class__ - это класс, к которому принадлежит объект. Итак, в вашем примере ситуация похожа на статические переменные. t2.__class__.derived_val относится к переменной, принадлежащей классу, а не к переменной, принадлежащей t2.

1

Другой способ (возможно, более кратким один), чтобы продемонстрировать это:

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"], []) 
Смежные вопросы