Скидка до 55% и 3 курса в подарок 2 дня 13 :30 :09 Выбрать курс
Код
#статьи

Классы и объекты в Python: руководство для начинающих

Разбираем ООП за готовкой печенья.

Иллюстрация: Polina Vari для Skillbox Media

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

У нас уже есть статья про основные принципы ООП, а в этом материале мы детально и на примерах изучим работу с классами и объектами в Python.

Содержание


Что такое классы и объекты в Python

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

Объект это конкретный экземпляр класса. Его можно представить как контейнер, в котором хранятся данные (атрибуты) и описаны действия, которые можно выполнять с этими данными (методы).

Чтобы лучше понять эту концепцию, рассмотрим пример из реальной жизни. Кондитер использует одну формочку, чтобы испечь партию печенья. Все печенья имеют одинаковую форму, но могут отличаться начинкой и вкусом. В этом примере формочка — это класс, а отдельные печенья — объекты этого класса.

Иллюстрация: Polina Vari для Skillbox Media

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

Как создать класс

Для создания классов в Python используется ключевое слово class. После него указывают имя класса с заглавной буквы и ставят двоеточие. Давайте создадим класс для печенья:

class Cookie:

Теперь добавим в класс конструктор — специальный метод __init__. Он вызывается при создании объекта и используется для инициализации его атрибутов. У нашего печенья будет два атрибута: вкус и начинка.

def __init__(self, flavor, filling):
        self.flavor = flavor        # Атрибут экземпляра: вкус
        self.filling = filling      # Атрибут экземпляра: начинка

Параметр self — это ссылка на текущий объект класса. Через него мы сохраняем значения аргументов внутри конкретного экземпляра.

Теперь добавим метод класса — функцию show_info, которая будет выводить информацию о печенье:

def show_info(self):
    return f"Печенье\nВкус: {self.flavor}\nНачинка: {self.filling}"

Полностью код класса Cookie выглядит так:

class Cookie:
    
    # Конструктор класса
    def __init__(self, flavor, filling):
        self.flavor = flavor        # Атрибут экземпляра: вкус
        self.filling = filling      # Атрибут экземпляра: начинка

    # Метод экземпляра
    def show_info(self):
        return f"Печенье\nВкус: {self.flavor}\nНачинка: {self.filling}"

Теперь вся логика, связанная с печеньем, описана в одном месте — внутри класса.

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

Чтобы создать объект, обратитесь к классу и передайте значения атрибутов в круглых скобках. В нашем примере используем класс Cookie и создадим два объекта: ванильное печенье с клубничной начинкой (vanilla_cookie) и шоколадное с марципаном (chocolate_cookie).

vanilla_cookie = Cookie("ваниль", "клубника")
chocolate_cookie = Cookie("шоколад", "марципан")

Теперь вызовем метод show_info, чтобы проверить, как выглядят наши объекты:

print(vanilla_cookie.show_info())
print(chocolate_cookie.show_info())

Если запустить код, то в терминале появится сообщение:

Печенье
Вкус: ваниль
Начинка: клубника

Печенье
Вкус: шоколад
Начинка: марципан

Кроме того, мы можем получить доступ к отдельным атрибутам объектов. Например, узнаем, какая начинка у печенек:

print(vanilla_cookie.flavor)
print(chocolate_cookie.filling)

Получим ответ в терминале:

ваниль
марципан

Как изменять объекты после создания

После создания объекта его атрибуты можно изменять. Например, превратить ванильное печенье в овсяное:

new_cookie = Cookie("ваниль", "клубника")
print(new_cookie.show_info())

new_cookie.flavor = "овсяное"
print(new_cookie.show_info())

В этом примере мы напрямую присваиваем атрибуту новое значение. В результате сначала выводятся исходные характеристики объекта, а затем — обновлённые:

Печенье
Вкус: ваниль
Начинка: клубника

Печенье
Вкус: овсяное
Начинка: клубника

Прямое изменение атрибутов работает быстро и просто, но у такого подхода есть ограничения. Если логика изменения состояния объекта становится сложнее — например, требует проверки данных или дополнительных действий, — прямое присваивание перестаёт быть удобным.

Поэтому в объектно-ориентированном программировании часто используют методы класса, которые отвечают за изменение состояния объекта.

Добавим в класс Cookie метод для замены начинки:

def change_filling(self, new_filling):
        self.filling = new_filling
        return "Начинка обновлена."

Теперь создадим объект шоколадного печенья и изменим его начинку с помощью метода change_filling:

chocolate_cookie = Cookie("шоколад", "марципан")
print(chocolate_cookie.show_info())

chocolate_cookie.change_filling("сливки") # Используем метод для замены начинки
print(chocolate_cookie.show_info())

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

Полностью код обновлённого метода Cookie выглядит так:

class Cookie:
    
    # Конструктор класса
    def __init__(self, flavor, filling):
        self.flavor = flavor        # Атрибут экземпляра: вкус
        self.filling = filling      # Атрибут экземпляра: начинка

    # Методы экземпляра
    def show_info(self):
        return f"Печенье\nВкус: {self.flavor}\nНачинка: {self.filling}\n"
        
    def change_filling(self, new_filling):
        self.filling = new_filling
        return "Начинка обновлена."

В Python можно добавлять новые атрибуты объекту даже после его создания — даже если они не описаны в классе. Например, можно создать объект печенья с атрибутами вкуса (flavor) и начинки (filling), а после добавить новый атрибут — тип посыпки (sprinkling):

chocolate_cookie = Cookie("шоколад", "марципан")
print(chocolate_cookie.show_info())

chocolate_cookie.sprinkling = "сахарная пудра"
print(chocolate_cookie.sprinkling)

Интерпретатор выполнит этот код без ошибок. Однако такой подход может привести к путанице. Атрибут sprinkling появится только у этого объекта. У других экземпляров класса Cookie его не будет.

Что такое деструктор

В Python существует специальный метод __del__, который называют деструктором. Он может быть вызван, когда объект удаляется из памяти.

Добавим деструктор в класс Cookie:

class Cookie:
    
    # Конструктор класса
    def __init__(self, flavor, filling):
        self.flavor = flavor        # Атрибут экземпляра: вкус
        self.filling = filling      # Атрибут экземпляра: начинка
        
    # Деструктор объекта
    def __del__(self): # Используем метод деструктора со ссылкой на сам объект
        print(f"Печенье удалено: вкус -- {self.flavor}, начинка -- {self.filling}") # Выводим сообщение о том, что объект удалён, указывая его атрибуты

Теперь при завершении программы деструктор будет автоматически удалять объекты класса Cookie.

Важно понимать, что в Python вызов деструктора не гарантирован. Интерпретатор сам управляет памятью и может не вызвать __del__ в ожидаемый момент — или не вызвать вовсе, например при завершении программы.

Поэтому деструкторы редко используют в прикладном коде. Для управления ресурсами (файлами, соединениями, потоками) в Python применяют другие механизмы — например, контекстные менеджеры (with) и явное освобождение ресурсов.

Практика

Закрепим теорию, решив практические задачи. Постарайтесь выполнить их самостоятельно перед тем, как подглядывать в ответы.

Задача 1

Создайте класс Book с атрибутами названия (title), автора (author) и года печати (year). В качестве метода добавьте функцию info (), которая будет выводить атрибуты в формате «Название — Автор (Год)».

Решение

class Book:
    def __init__(self, title, author, year):
        self.title = title
        self.author = author
        self.year = year

    def info(self):
        return f"{self.title} -- {self.author} ({self.year})"

# Пример использования класса
new_book = Book("Мастер и Маргарита", "Михаил Булгаков", 1967)
print(new_book.info())

Вот что должно получиться в терминале при запуске кода:

Мастер и Маргарита -- Михаил Булгаков (1967)

Задача 2

Создайте класс Account для банковского счёта с атрибутами владельца (owner) и баланса (balance). Добавьте методы для пополнения счёта (deposit) и для снятия наличных (withdraw). Помните, что нельзя уводить баланс владельца в минус.

С помощью класса создайте объект и проведите с ним три операции пополнения и снятия. Порядок операций и сумму выберите сами. В конце выведите остаток на счету.

Решение

class Account:
    def __init__(self, owner, balance=0):
        self.owner = owner
        self.balance = float(balance)

    def deposit(self, amount):
        amount = float(amount)

        if amount <= 0:
            return "Сумма пополнения должна быть больше 0."

        self.balance += amount
        return f"Пополнение: +{amount:.2f}. Баланс: {self.balance:.2f}"

    def withdraw(self, amount):
        amount = float(amount)

        if amount <= 0:
            return "Сумма снятия должна быть больше 0."

        if amount > self.balance:
            return f"Ошибка: недостаточно средств. Баланс: {self.balance:.2f}"

        self.balance -= amount
        return f"Снятие: -{amount:.2f}. Баланс: {self.balance:.2f}"

    def info(self):
        return f"Счёт: {self.owner}\nБаланс: {self.balance:.2f}"


# Операции со счётом
acc = Account("Василий", 100)

print(acc.deposit(50))    # 1) пополнение
print(acc.withdraw(30))   # 2) снятие
print(acc.withdraw(200))  # 3) попытка снять больше, чем есть на счету

print("\nИтог:")
print(acc.info())

Вот что программа выведет в терминал:

Пополнение: +50.00. Баланс: 150.00
Снятие: -30.00. Баланс: 120.00
Ошибка: недостаточно средств. Баланс: 120.00

Итог:
Счёт: Tom
Баланс: 120.00

Больше интересного про код — в нашем телеграм-канале.  Подписывайтесь!



Python для всех

Вы освоите Python на практике и создадите проекты для портфолио — телеграм-бот, веб-парсер и сайт с нуля. А ещё получите готовый план выхода на удалёнку и фриланс. Спикер — руководитель отдела разработки в «Сбере».

Пройти бесплатно
Листая дальше, вы перейдете на страницу Python для всех: старт в IT с нуля



Бесплатный курс по разработке на Python ➞
Пройдите бесплатный курс по Python и создайте с нуля телеграм-бот, веб-парсер и сайт. Спикер — руководитель отдела разработки в «Сбере».
Пройти курс
Понравилась статья?
Да

Пользуясь нашим сайтом, вы соглашаетесь с тем, что мы используем cookies 🍪

Ссылка скопирована