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

Основы классов в Python

4 min read Программирование Обновлено 18 Dec 2025
Основы классов Python — пример Car
Основы классов Python — пример Car

Спортивный автомобиль на дороге

Основная идея

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

В Python всё — объект, и каждая сущность является экземпляром некоторого класса. Класс объединяет общие методы (поведения) и структуру данных (атрибуты) для всех его экземпляров.

Важно: в примере ниже класс Car моделирует сенсор, который добавляет штраф в 50 долларов, если скорость превышает порог 140 миль/ч (≈225 км/ч).

Исправленный и улучшенный пример класса Car

Ниже — корректный и аккуратно отформатированный пример класса на Python с русскими комментариями и базовой проверкой типов. Этот вариант безопаснее и удобнее для практики.

class Car:
    """Модель автомобиля.

    Атрибуты экземпляра:
      _car_name, _driver_name, _license_plate, _current_speed,
      _speeding_charge, _colour
    """

    SPEED_LIMIT_MPH = 140  # порог скорости в милях/ч
    SPEEDING_FINE_USD = 50  # штраф в долларах

    def __init__(self, car_name, driver_name, license_plate_number,
                 current_speed=0, speeding_charge=0, colour="Unknown"):
        # Инициализируем атрибуты экземпляра
        self._car_name = str(car_name)
        self._driver_name = str(driver_name)
        self._license_plate = str(license_plate_number)
        self._current_speed = float(current_speed)
        self._speeding_charge = float(speeding_charge)
        self._colour = str(colour)

    # Accessor-методы (геттеры)
    def get_car_name(self):
        return self._car_name

    def get_driver_name(self):
        return self._driver_name

    def get_license_plate(self):
        return self._license_plate

    def get_current_speed(self):
        return self._current_speed

    def get_speeding_charge(self):
        return self._speeding_charge

    def get_colour(self):
        return self._colour

    # Mutator-методы (сеттеры и действия)
    def set_driver(self, new_driver):
        self._driver_name = str(new_driver)

    def speeding_ticket(self, current_speed):
        """Проверяет скорость и добавляет штраф, если превышен лимит.

        Возвращает True, если штраф добавлен, иначе False.
        """
        try:
            speed = float(current_speed)
        except (TypeError, ValueError):
            raise ValueError("current_speed должен быть числом")

        self._current_speed = speed
        if speed <= self.SPEED_LIMIT_MPH:
            return False
        else:
            self._speeding_charge += self.SPEEDING_FINE_USD
            return True

    def make_payment(self, amount_paid):
        """Вычисляет оплату штрафа. amount_paid должен быть числом >= 0."""
        try:
            amount = float(amount_paid)
        except (TypeError, ValueError):
            raise ValueError("amount_paid должен быть числом")
        if amount < 0:
            raise ValueError("amount_paid не может быть отрицательным")
        self._speeding_charge = max(0.0, self._speeding_charge - amount)

Пример создания экземпляра:

# создаём экземпляр автомобиля
my_car = Car("Bugatti", "David Sasu", 90828, 0, 0, "Cherry Red")

# проверяем штраф за скорость
my_car.speeding_ticket(150)  # True, добавлен штраф $50
print(my_car.get_speeding_charge())  # 50.0

# вносим оплату
my_car.make_payment(20)
print(my_car.get_speeding_charge())  # 30.0

Пояснение ключевых концепций

Параметр self

self — это ссылка на конкретный экземпляр класса. В сигнатуре методов он передаётся явно, но при вызове метода на экземпляре программист его не указывает. Это связывает атрибуты и методы с текущим объектом.

Конструктор

Метод init создаёт и инициализирует новый объект. В нашем примере конструктор устанавливает шесть полей экземпляра: _car_name, _driver_name, _license_plate, _current_speed, _speeding_charge, _colour.

Геттеры и сеттеры

Геттеры (accessors) возвращают текущее состояние атрибутов. Сеттеры (mutators) и другие методы изменяют состояние объекта (например, set_driver, speeding_ticket, make_payment).

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

Инкапсуляция означает, что внутреннее состояние объекта скрыто и изменяется только через публичные методы. В Python соглашение об имени с подчёркиванием (например, _driver_name) обозначает «внутреннее» поле.

Ошибки и проверка входных данных

Наш первоначальный пример был уязвим к ошибкам — функции не проверяли типы входных данных. В исправленном варианте мы:

  • Приводим значения к нужным типам (str, float) в конструкторе;
  • Бросаем понятные исключения ValueError при некорректных аргументах;
  • Предотвращаем отрицательное значение штрафа при оплате.

Важно: всегда валидируйте входные данные в публичных методах, чтобы избежать неожиданных падений.

Когда такой класс может не подойти (примеры и ограничения)

  • Многопоточная среда: при одновременном доступе к одному объекту нужна синхронизация.
  • Более сложные правила начисления штрафа: если нужно учитывать гео-данные или временные окна — бизнес-логика усложнится.
  • Международные единицы: если система должна работать с км/ч и милями/ч — нужно добавить параметр единиц.

Альтернативные подходы

  • Использовать dataclass для автоматической генерации методов и упрощённой сериализации:
from dataclasses import dataclass

@dataclass
class CarData:
    car_name: str
    driver_name: str
    license_plate: str
    current_speed: float = 0.0
    speeding_charge: float = 0.0
    colour: str = "Unknown"
  • Разделять ответственность: выделить отдельный объект SpeedingPolicy для расчёта штрафов.

Умственная модель и эвристики

  • Класс = шаблон; экземпляр = конкретный объект с собственными данными.
  • Методы изменяют состояние; геттеры читают состояние.
  • Инкапсуляция скрывает внутренние детали, одновременно давая контролируемый API.

Факт-бокс

  • Порог в примере: 140 миль/ч (≈225 км/ч).
  • Штраф в примере: $50.
  • Поля экземпляра: 6.

Тесты и критерии приёмки

Критерии приёмки:

  • При скорости ≤ 140 штраф не добавляется.
  • При скорости > 140 штраф увеличивается ровно на 50.
  • make_payment корректно уменьшает _speeding_charge и не делает значение отрицательным.
  • Методы бросают ValueError при некорректных типах аргументов.

Минимальные тест-кейсы (pytest):

def test_no_ticket_below_limit():
    c = Car("A", "B", 1, 100)
    assert not c.speeding_ticket(100)
    assert c.get_speeding_charge() == 0

def test_ticket_above_limit():
    c = Car("A", "B", 1, 0)
    assert c.speeding_ticket(141)
    assert c.get_speeding_charge() == 50

def test_make_payment():
    c = Car("A", "B", 1, 0, 100)
    c.make_payment(30)
    assert c.get_speeding_charge() == 70

def test_invalid_speed():
    c = Car("A", "B", 1)
    try:
        c.speeding_ticket("fast")
        assert False, "Expected ValueError"
    except ValueError:
        assert True

Роль‑ориентированные чек‑листы

Для разработчика:

  • Написать проверку типов и документацию.
  • Добавить модульные тесты.
  • Поддерживать инварианты (например, штраф ≥ 0).

Для ревьюера:

  • Проверить обработку исключений и граничные случаи.
  • Убедиться, что публичный API стабилен.

Для тестировщика:

  • Тесты на граничные скорости: 140, 140.0, 140.1.
  • Тесты на некорректные типы и негативные оплаты.

Краткий глоссарий

  • Класс: шаблон для объектов.
  • Экземпляр (объект): конкретный объект, созданный по шаблону класса.
  • Метод: функция, связанная с классом/объектом.
  • Атрибут: поле данных объекта.
  • Инкапсуляция: скрытие внутреннего состояния за публичным API.

Заключение

Вы узнали, что класс в Python задаёт поведение и состояние объектов, как работает параметр self, зачем нужны геттеры и сеттеры и почему важно валидировать входные данные. Исправленный пример класса Car показывает практические приёмы: явное приведение типов, понятные исключения и простую бизнес‑логику для штрафов.

Короткий план следующего шага: реализуйте класс, напишите тесты из раздела «Тесты и критерии приёмки», затем выделите политику начисления штрафов в отдельный класс, если требования усложняются.

Важно: порог скорости указан в милях в исходном примере; при локализации интерфейса для пользователей добавьте возможность выбора единиц (mph / km/h).

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

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

Изменить валюту по умолчанию в Windows
Windows

Изменить валюту по умолчанию в Windows

Симулятор рассвета из умных ламп
Умный дом

Симулятор рассвета из умных ламп

Очистка старых Jobs в Kubernetes
Kubernetes

Очистка старых Jobs в Kubernetes

VBA форма для ввода студентов в Excel
Excel VBA

VBA форма для ввода студентов в Excel

Как включить режим Санты в Waze
Навигация

Как включить режим Санты в Waze

Как заблокировать Android для детей
Родительский контроль

Как заблокировать Android для детей