все Python 3ООПпонятие
Атрибуты экземпляра и класса
атрибуты
Атрибуты класса — общие для всех экземпляров. Атрибуты экземпляра — уникальные для каждого. Изменяемые атрибуты класса — ловушка!
Синтаксис
class C:
class_attr = 0 # классовый
def __init__(self):
self.inst_attr = 1 # экземплярный
Чтение атрибута сперва ищет его в экземпляре, потом в классе, а присваивание self.attr = ... всегда создаёт атрибут экземпляра, заслоняя классовый. Настоящая ловушка — не переприсваивание, а мутация общего изменяемого классового атрибута (например через append): она меняет его сразу для всех экземпляров.
Примеры
class Dog:
species = 'Canis lupus' # классовый
def __init__(self, name):
self.name = name # экземплярный
d1 = Dog('Rex')
d2 = Dog('Max')
print(d1.species, d2.species) # → Canis lupus Canis lupus
print(d1.name, d2.name) # → Rex Max
# Изменение классового атрибута через класс
Dog.species = 'Canis familiaris'
print(d1.species) # → Canis familiaris
# Затенение классового атрибута
d1.species = 'Wolf' # только у d1
print(d1.species) # → Wolf
print(d2.species) # → Canis familiaris
# Изменяемый классовый атрибут — ловушка!
class BadList:
items = [] # общий для всех!
b1 = BadList(); b2 = BadList()
b1.items.append(1)
print(b2.items) # → [1] (список общий на всех — ловушка)
class GoodList:
def __init__(self):
self.items = [] # каждому свой
g1 = GoodList(); g2 = GoodList()
g1.items.append(1)
print(g2.items) # → []
class Counter2:
count = 0
def __init__(self):
Counter2.count += 1
self.id = Counter2.count
Counter2(); c3 = Counter2()
print(c3.id, Counter2.count) # → 2 2
# vars() vs dir()
class A:
x = 1
def __init__(self):
self.y = 2
a = A()
print(vars(a)) # → {'y': 2} (только экземплярные)
См. также
Открыть в полном глоссарииdocs.python.orgСообщить о неточности