ООП Python

Когда программа моделирует что-то из реального мира — банковский счёт, пользователя, машину — у этой сущности обычно есть данные (баланс, имя, скорость) и действия (внести деньги, представиться, ускориться). Объектно-ориентированное программирование (ООП) позволяет упаковать данные и действия в одну сущность — объект, описанный шаблоном — классом.

Первый пример

Опишем простой класс Car:

Python 3.13
class Car:
    def __init__(self, make, model):
        self.make = make           # марка
        self.model = model         # модель
        self.is_running = False    # двигатель заведён или нет

    def start_engine(self):
        """Запуск двигателя"""
        if not self.is_running:
            self.is_running = True
            return f"{self.make} {self.model}: Двигатель запущен"
        return f"{self.make} {self.model}: Двигатель уже был запущен"

    def stop_engine(self):
        """Остановка двигателя"""
        if self.is_running:
            self.is_running = False
            return f"{self.make} {self.model}: Двигатель остановлен"
        return f"{self.make} {self.model}: Двигатель уже был остановлен"

# Создаём экземпляр класса Car
my_car = Car("Toyota", "Corolla")
print(my_car.start_engine())
Toyota Corolla: Двигатель запущен
print(my_car.stop_engine())
Toyota Corolla: Двигатель остановлен
# Можем создать ещё один экземпляр класса Car
another_car = Car("Honda", "Civic")
print(another_car.start_engine())
Honda Civic: Двигатель запущен

Класс vs объект

Car это класс — шаблон, описывающий, какие поля и методы будут у любого автомобиля. my_car и another_car это объекты (экземпляры класса) с конкретными значениями этих полей. Из одного класса можно создавать сколько угодно объектов, каждый со своими данными.

Класс Car как шаблон с полями make, model, is_running и методами start_engine, stop_engine. Из этого класса создаются два объекта: my_car (Toyota Corolla, running=True) и another_car (Honda Civic, running=False)

Терминология

Привязываемся к примеру выше:

  • Car: класс (blueprint)
  • my_car, another_car: экземпляры или объекты этого класса
  • make, model, is_running: атрибуты (данные объекта)
  • start_engine(), stop_engine(): методы (действия объекта)
  • __init__: специальный метод-конструктор, вызывается автоматически при создании объекта через Car(...)
  • self: ссылка на сам объект; через неё методы видят свои атрибуты

Четыре принципа ООП

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

  1. Инкапсуляция — упаковка данных и методов, которые с этими данными работают, в один объект. Внешний код не лезет в детали реализации, а работает через интерфейс класса.
  2. Наследование — создание нового класса на основе существующего с переиспользованием его атрибутов и методов.
  3. Полиморфизм — возможность работать с объектами разных классов через единый интерфейс (одинаково вызвать .area() у круга, квадрата и треугольника).
  4. Абстракция — выделение существенных характеристик объекта, скрытие неважных деталей.

Практический пример: банковский счёт

Соберём более содержательный класс, где есть и валидация, и состояние:

Python 3.13
class BankAccount:
    def __init__(self, owner, balance=0):
        self.owner = owner
        self.balance = balance

    def deposit(self, amount):
        if amount > 0:
            self.balance += amount
            return f"Внесено {amount} руб. Новый баланс: {self.balance} руб."
        return "Сумма депозита должна быть положительной"

    def withdraw(self, amount):
        if amount > 0:
            if amount <= self.balance:
                self.balance -= amount
                return f"Снято {amount} руб. Новый баланс: {self.balance} руб."
            return "Недостаточно средств"
        return "Сумма снятия должна быть положительной"

    def get_balance(self):
        return f"Баланс счёта {self.owner}: {self.balance} руб."

account = BankAccount("Иван Петров", 1000)

print(account.get_balance())
Баланс счёта Иван Петров: 1000 руб.
print(account.deposit(500))
Внесено 500 руб. Новый баланс: 1500 руб.
print(account.withdraw(200))
Снято 200 руб. Новый баланс: 1300 руб.
print(account.withdraw(2000))
Недостаточно средств

Объект account хранит данные (owner, balance) и предоставляет действия (deposit, withdraw, get_balance). Логика валидации (положительная сумма, достаточно средств) живёт внутри методов, рядом с данными, к которым относится. Это и есть инкапсуляция в работе.

Проверка понимания

Какие основные принципы лежат в основе ООП?


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