Глава 14 · Создаём объекты реального мира

Композиция: объекты внутри объектов

Один объект может ХРАНИТЬ другие объекты, отвечая за них — так был устроен Uchastnik ещё в разделе 14.4.

Объект как атрибут другого объекта

В разделе 14.4 класс Uchastnik хранил объект turtle.Turtle в своём атрибуте self.t — не наследовал от него, а именно ХРАНИЛ. Это называется композицией: один объект строится ИЗ других объектов, отвечая за них.

Uchastnikturtle.TurtleHAS-A
Композиция: Uchastnik ХРАНИТ Turtle в своём атрибуте self.t
Правило именования отношений: HAS-A
Композицию легко проверить вопросом «X — это Y?» или «X ИМЕЕТ Y?». Uchastnik не является черепашкой (HAS-A верно, IS-A неверно) — поэтому это композиция, а не наследование (о нём — в разделе 14.15).

Объектный граф: композиция может идти в глубину

Объект может хранить не только один объект, а целый список объектов — и те, в свою очередь, могут хранить свои:

Zakaz
Tovar('Книга', 590)
Tovar('Ручка', 90)
Tovar('Тетрадь', 120)
Zakaz хранит СПИСОК объектов Tovar — композиция, где владелец хранит несколько объектов сразу
Debug Lab 7: перепутали уровень вложенности атрибута
propushchennyj_uroven.py
class Mashina:
    def __init__(self):
        self.dvigatel = Dvigatel()

mashina = Mashina()
mashina.start()     # а где именно определён start()?
Traceback (most recent call last):
  File "propushchennyj_uroven.py", line 5, in 
    mashina.start()
AttributeError: 'Mashina' object has no attribute 'start'
Что видно на экране

start() определён у Dvigatel, а не у Mashina — при композиции методы вложенного объекта НЕ становятся автоматически методами владельца. Нужно обратиться явно, через тот атрибут, в котором вложенный объект хранится.

Исправленный код
cherez_atribut.py
mashina.dvigatel.start()   # явно: через self.dvigatel
Практика: композиция
Интерактивный ноутбук прямо в браузере — Python 3.14 через Pyodide, без установки
Открыть практику →