Python Glossary English

все 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Сообщить о неточности