Атрибут класса 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. class.derived_val имеют другой адрес памяти. Моя проблема - это производный_value атрибут класса. Почему в приведенном выше примере это отличается? Это потому, что экземпляр класса копирует свой собственный производный_val рядом с атрибутом класса?

Ответы

Ответ 1

Существуют атрибуты класса и атрибуты экземпляра. Когда вы скажете

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 пытается найти 'производный_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, но только атрибут экземпляра легко доступен. Атрибут class становится доступным только путем ссылки base.derived_val или прямого доступа к классу dict base.__dict__.

Ответ 2

Проверьте здесь и здесь.

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

Ответ 3

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

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