Основы Python

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

ООП организует программу вокруг объектов, которые хранят состояние и предоставляют поведение через понятные интерфейсы.

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

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

Четыре основных принципа ООП

  • Инкапсуляция объединяет состояние и поведение и контролирует доступ.
  • Абстракция показывает полезный интерфейс и скрывает лишние детали.
  • Наследование специализирует класс только при настоящем отношении «является».
  • Полиморфизм применяет одну операцию к разным объектам с подходящим поведением.

Устройство примера

  1. BankAccount хранит баланс и проверяет пополнение.
  2. SavingsAccount повторно использует базовый контракт.
  3. SavingsAccount переопределяет month_end для начисления процентов.
  4. Цикл использует единый интерфейс для всех счетов.
Совет: Предпочитайте композицию, если объект лишь использует другой; наследуйте только при корректной взаимозаменяемости.

Базовый пример

Запустить код →
main.py
class BankAccount:
    def __init__(self, owner, balance=0):
        self.owner = owner
        self._balance = float(balance)

    @property
    def balance(self):
        return self._balance

    def deposit(self, amount):
        if amount <= 0:
            raise ValueError("Deposit must be positive")
        self._balance += amount

    def month_end(self):
        return "No interest"


class SavingsAccount(BankAccount):
    def __init__(self, owner, balance, interest_rate):
        super().__init__(owner, balance)
        self.interest_rate = interest_rate

    def month_end(self):
        self._balance *= 1 + self.interest_rate
        return "Interest applied"


accounts = [
    BankAccount("Ada", 100),
    SavingsAccount("Lin", 200, 0.05),
]
accounts[0].deposit(50)

for account in accounts:
    status = account.month_end()
    print(f"{account.owner}: {account.balance:.2f} ({status})")

Ожидаемый результат

Ada: 150.00 (No interest)
Lin: 210.00 (Interest applied)

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

Эти примеры показывают, как Python реализует инкапсуляцию, абстракцию, наследование и полиморфизм в повседневном коде.

Инкапсуляция

Запустить код →

Инкапсуляция объединяет состояние и поведение и контролирует доступ.

encapsulation.py
class BankAccount:
    def __init__(self, balance=0):
        # Double underscores prevent accidental direct access.
        self.__balance = balance

    @property
    def balance(self):
        # Expose read access without exposing mutation.
        return self.__balance

    def deposit(self, amount):
        # Keep validation next to the state it protects.
        if amount <= 0:
            raise ValueError("Amount must be positive")
        self.__balance += amount


account = BankAccount(100)
account.deposit(50)
print(account.balance)  # 150

Абстракция

Запустить код →

Абстракция показывает полезный интерфейс и скрывает лишние детали.

abstraction.py
from abc import ABC, abstractmethod


class PaymentMethod(ABC):
    @abstractmethod
    def pay(self, amount):
        # Callers know what pay does, not how each provider does it.
        pass


class CreditCard(PaymentMethod):
    def pay(self, amount):
        # The concrete class hides its payment implementation.
        return f"Paid ${amount:.2f} by card"


payment = CreditCard()
print(payment.pay(25))

Наследование

Запустить код →

Наследование специализирует класс только при настоящем отношении «является».

inheritance.py
class Employee:
    def __init__(self, name):
        self.name = name

    def describe(self):
        return self.name


class Developer(Employee):
    def __init__(self, name, language):
        # Reuse initialization from the parent class.
        super().__init__(name)
        self.language = language

    def describe(self):
        # Extend inherited behavior instead of duplicating it.
        return f"{super().describe()} writes {self.language}"


print(Developer("Ada", "Python").describe())

Полиморфизм

Запустить код →

Полиморфизм применяет одну операцию к разным объектам с подходящим поведением.

polymorphism.py
class EmailNotification:
    def send(self, message):
        return f"Email: {message}"


class SmsNotification:
    def send(self, message):
        return f"SMS: {message}"


def notify(channels, message):
    for channel in channels:
        # The same call selects behavior from each concrete object.
        print(channel.send(message))


channels = [EmailNotification(), SmsNotification()]
notify(channels, "Order shipped")

Как это работает

BankAccount инкапсулирует баланс. SavingsAccount наследует интерфейс и переопределяет month_end. Цикл одинаково работает с обоими объектами, а Python выбирает метод во время выполнения.

Измените значения и запустите программу в онлайн-компиляторе Python CodeUtility без локальной установки Python.

Практические задания

Изменяйте входные данные и проверяйте граничные случаи перед работой с большими наборами.

  1. Предскажите результат до запуска.
  2. Обработайте пустой и некорректный ввод.
  3. Вынесите логику в функцию и добавьте тесты.
Запустить в Python IDE →