Гид по технологиям

Объектно-ориентированное программирование в Python

5 min read Python Обновлено 07 Apr 2026
ООП в Python: основы и примеры
ООП в Python: основы и примеры

Два человека сидят друг напротив друга, на экране спереди виден логотип Python

Объектно-ориентированное программирование (ООП) — парадигма, в которой основными строительными блоками являются объекты: небольшие единицы, сочетающие данные и код. Первая языковая реализация ООП возникла в Simula для моделирования физических процессов. В Python вы определяете классы как шаблоны для объектов определённых типов и используете объекты для хранения состояния и выполнения логики.

Что такое ООП в Python?

Python — это универсальный язык программирования с полной поддержкой ООП. Он даёт простой синтаксис для описания классов, создания экземпляров и управления поведением через методы. Преимущества: код становится более структурированным, легче поддерживается и реиспользуется.

Коротко о ключевых понятиях:

  • Класс: шаблон или «чертёж» для объектов одного типа.
  • Объект (экземпляр): конкретный экземпляр класса с собственным состоянием.
  • Атрибут: переменная класса или экземпляра, описывающая состояние.
  • Метод: функция внутри класса, описывающая поведение.
  • Инкапсуляция: скрытие внутренней реализации за понятным интерфейсом.
  • Наследование: возможность описать новый класс на основе существующего.
  • Полиморфизм: единый интерфейс для разных типов.

Важно: ООП — инструмент, а не строгая необходимость. Выбирайте парадигму, которая делает код проще в контексте вашей задачи.

Почему простые структуры могут быть проблемой

Рассмотрим негибкий пример без ООП:

jeans = [30, True, "Denim", 59]

Здесь список хранит размер, признак распродажи, материал и цену. Но код становится неочевидным: что именно означает jeans[0]? Такой код сложнее читать и рефакторить. В ООП мы бы использовали именованный атрибут: jeans.size — и смысл становится явным.

Как определить класс в Python

Чтобы создать класс, используйте ключевое слово class и имя класса (с заглавной буквы по соглашению). Простой пример:

class MyClass:
    x = 2

p1 = MyClass()
print(p1.x)

Пример класса для описания брюк (Pant):

class Pant:
    # Свойства класса или значения по умолчанию
    size = None
    onsale = None
    material = None
    price = None

Здесь мы задали атрибуты по умолчанию. Обычно для значений, специфичных для экземпляра, используют инициализатор init.

Как создать объект в Python

Инициализатор класса называется init (две нижние черты до и после). Параметр self внутри методов ссылается на конкретный экземпляр класса.

class Pant:
    # Инициализатор экземпляра
    def __init__(self, size, onsale, material, price):
        self.size = size
        self.onsale = onsale
        self.material = material
        self.price = price

# Создаём объект класса Pant и задаём значения
jeans = Pant(30, False, "Denim", 81)

После создания объекта его атрибуты доступны как jeans.size, jeans.onsale и т. д.

Атрибуты и методы: свойства и поведение

В Python есть два вида атрибутов:

  • Атрибуты класса: разделяются всеми экземплярами (например, константа или счётчик).
  • Атрибуты экземпляра: уникальны для каждого объекта.

Добавим методы для отображения информации и для пометки товара как распроданного:

class Pant:
    def __init__(self, size, onsale, material, price):
        self.size = size
        self.onsale = onsale
        self.material = material
        self.price = price

    # Метод экземпляра: возвращает строку с описанием
    def printinfo(self):
        return f"Эти брюки размера {self.size}, материал {self.material}, цена {self.price}"

    # Метод экземпляра: пометить как распродажу
    def putonsale(self):
        self.onsale = True

jeans = Pant(30, False, "Denim", 81)
print(jeans.printinfo())
jeans.putonsale()
print(jeans.onsale)

Обратите внимание: вызов putonsale() изменит только текущий объект jeans; другие экземпляры останутся нетронутыми.

Наследование: расширение функциональности

Наследование позволяет создавать подклассы на основе существующих классов, переиспользуя код и расширяя его.

# Leggings — подкласс Pant, добавляет свойство elasticity
class Leggings(Pant):
    def __init__(self, size, onsale, material, price, elasticity):
        super().__init__(size, onsale, material, price)  # вызываем инициализатор родителя
        self.elasticity = elasticity

    # Переопределяем метод печати информации
    def printinfo(self):
        return f"Эти леггинсы размера {self.size}, материал {self.material}, цена {self.price}"

leggings = Leggings(30, False, "Leather", 42, True)
print(leggings.printinfo())

Если бы мы не использовали наследование, нам пришлось бы копировать код и поддерживать его в двух местах.

Как проверить тип объекта с помощью isinstance()

isinstance(obj, Class) возвращает True, если obj является экземпляром Class или подкласса Class.

class Pant:
    pass

class Leggings(Pant):
    pass

pants = Pant()
leggings = Leggings()

print(isinstance(leggings, Pant))  # True, потому что Leggings наследует Pant
print(isinstance(pants, Leggings))  # False

Это полезно для проверки совместимости типов или при реализации полиморфизма.

Когда ООП может не подойти

  • Простые скрипты и одноразовые задачи: процедурный подход проще и быстрее.
  • Задачи, где важна высокая скорость и предсказуемость (например, в узконаправленных алгоритмах), — лишняя объектная абстракция может добавить накладные расходы.
  • Функциональные трансформации данных: функциональный стиль делает код компактнее и легче для параллелизма.

Контрпример: маленький утилитный скрипт для анализа логов вероятно выигрывает от простых функций и модулей, а не от полной ООП-архитектуры.

Альтернативы и гибриды

  • Процедурный стиль: функции и структуры данных (dict, list).
  • Функциональный стиль: чистые функции, неизменяемые структуры, map/filter.
  • Компонентный подход: объекты без глубоких иерархий, композиция вместо наследования.

Совет: использовать композицию (встраивание объектов) когда наследование ведёт к жесткой связи между классами.

Хорошие практики и эвристики

  • Правило единой ответственности: класс должен отвечать за одну чёткую задачу.
  • Предпочитайте композицию наследованию, если поведение можно собрать из отдельных компонентов.
  • Используйте приватные атрибуты (_attr) для сигнализации о внутреннем API.
  • Пишите короткие методы (обычно < 20 строк) и не смешивайте уровни абстракции.

Ментальная модель: класс = сущность + операции над ней. Думайте о классах как о «контрактах» для данных и поведения.

Рольовые чек-листы при разработке

Для новичка:

  • Понимаю ли я, что инкапсулирую в классе?
  • Нужен ли атрибут на уровне экземпляра или класса?
  • Есть ли тесты для методов?

Для разработчика среднего уровня:

  • Нет ли дублирования кода между классами (возможно, нужен базовый класс)?
  • Есть ли у класса одна ответственность?
  • Использую ли я super() корректно?

Для технического лидера:

  • Соответствует ли дизайн архитектурным требованиям?
  • Легко ли расширять поведение без изменения существующего кода?
  • Есть ли набор интеграционных тестов для ключевых компонентов?

Критерии приёмки (минимальные тесты)

  • Создание экземпляра класса Pant с корректными значениями.
  • Метод printinfo возвращает ожидаемую строку (проверка подстрок).
  • putonsale меняет onsale на True только у текущего экземпляра.
  • Для Leggings isinstance(leggings, Pant) возвращает True.

Небольшая методология для перехода к ООП в проекте

  1. Выделите понятные доменные сущности (например: User, Order, Product).
  2. Опишите состояние и поведение каждой сущности в виде атрибутов и методов.
  3. Предпочитайте небольшие классы и композицию.
  4. Напишите простые unit-тесты для ключевых методов.
  5. Рефакторьте постепенно, чтобы не ломать существующую функциональность.

1-строчный глоссарий

  • Экземпляр: конкретный объект класса.
  • Инициализатор (init): метод, создающий и настраивающий экземпляр.
  • Полиморфизм: объекты разных классов отвечают на один вызов одинаково.
  • Инкапсуляция: скрытие деталей реализации.

Важно: ООП упрощает разработку крупных и сложных систем, но не является панацеей. Выбирайте подход, исходя из задач и команды.

Короткое резюме

  • ООП в Python помогает организовать код через классы и объекты.
  • Используйте атрибуты и методы для моделирования состояния и поведения.
  • Наследование и isinstance() помогают строить иерархии типов, а композиция часто предпочтительнее наследования.
  • Тестируйте и рефакторьте постепенно, следуя принципам единой ответственности и простоты.

Если вы начинаете изучать разработку, Python и ООП — отличная отправная точка для построения читаемого, масштабируемого кода.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Папка автозагрузки Windows — найти и управлять
Windows

Папка автозагрузки Windows — найти и управлять

Отключить исчезновение окон в macOS Sonoma
macOS

Отключить исчезновение окон в macOS Sonoma

Отключить клавишу Globe на Mac
macOS

Отключить клавишу Globe на Mac

Отключить миниатюры скриншотов на Mac
macOS

Отключить миниатюры скриншотов на Mac

RAW в JPEG на Mac — через Preview
Фото

RAW в JPEG на Mac — через Preview

Удалить фон с фото на Mac — быстро и без программ
macOS

Удалить фон с фото на Mac — быстро и без программ