Атрибут класса 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"], [])