Python Glossary Русский

all Python 3OOPterm

Instance and class attributes

attributes

Class attributes are shared by every instance. Instance attributes belong to one instance each. Mutable class attributes are a trap!

Syntax

class C:
    class_attr = 0  # классовый
    def __init__(self):
        self.inst_attr = 1  # экземплярный

Reading an attribute checks the instance first, then the class, but self.attr = ... always creates an instance attribute that shadows the class one. The real trap isn't reassignment — it's mutating a shared mutable class attribute (say, appending to a class-level list), which changes it for every instance at once.

Examples

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} (только экземплярные)

See also

Open in the full glossarydocs.python.orgReport an inaccuracy