Python

Классы в Python: простой пример

Класс в Python описывает объект: какие данные он хранит и какие действия умеет выполнять. Если функция — это именованное действие, то класс объединяет данные и действия вокруг одной сущности

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

По этой теме полезно отдельно посмотреть Составьте еженедельное расписание занятий, чтобы расширить контекст и сравнить подходы

По этой теме полезно отдельно посмотреть Аннотации типов для декораторов в Python, чтобы расширить контекст и сравнить подходы

Первый класс

class Task:
    def __init__(self, title):
        self.title = title
        self.done = False

task = Task('написать код')

print(task.title)
print(task.done)

Результат:

написать код
False

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

Что делает __init__

Метод __init__ вызывается при создании объекта

task = Task('написать код')

Python создает новый объект и передает значение 'написать код' в параметр title. Внутри __init__ мы сохраняем это значение в self.title

self.title = title
self.done = False

self.title и self.done — атрибуты объекта. Они принадлежат конкретной задаче

Зачем нужен self

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

class Task:
    def __init__(self, title):
        self.title = title
        self.done = False

    def describe(self):
        return f'{self.title}: {self.done}'

task = Task('написать код')
print(task.describe())

Результат:

написать код: False

Когда вы вызываете task.describe(), Python сам передает объект task в параметр self

Метод, который меняет объект

Добавим действие mark_done()

class Task:
    def __init__(self, title):
        self.title = title
        self.done = False

    def mark_done(self):
        self.done = True

    def describe(self):
        status = 'готово' if self.done else 'в работе'
        return f'{self.title}: {status}'

task = Task('написать код')

print(task.describe())
task.mark_done()
print(task.describe())

Результат:

написать код: в работе
написать код: готово

Метод mark_done() меняет состояние объекта. После вызова task.done становится True

Несколько объектов одного класса

Класс — это шаблон. Объект — конкретный экземпляр

task1 = Task('написать код')
task2 = Task('запустить тесты')

task1.mark_done()

print(task1.describe())
print(task2.describe())

Результат:

написать код: готово
запустить тесты: в работе

У task1 и task2 свои значения title и done. Изменение одного объекта не меняет другой

Список объектов

Объекты можно хранить в списке

tasks = [
    Task('написать код'),
    Task('запустить тесты'),
    Task('опубликовать'),
]

tasks[0].mark_done()

for task in tasks:
    print(task.describe())

Такой подход уже похож на маленькую модель данных для приложения. Вместо разрозненных словарей у каждой задачи есть понятные методы

Метод rename

Добавим переименование

class Task:
    def __init__(self, title):
        self.title = title
        self.done = False

    def mark_done(self):
        self.done = True

    def rename(self, new_title):
        self.title = new_title

    def describe(self):
        status = 'готово' if self.done else 'в работе'
        return f'{self.title}: {status}'

task = Task('старое название')
task.rename('новое название')

print(task.describe())

Методы нужны не только для вывода. Они помогают менять объект понятным способом

Когда класс полезен

Класс стоит использовать, когда у сущности есть несколько связанных данных и действий

Хорошие примеры:

  • пользователь с именем, ролью и методом проверки прав
  • задача с названием, статусом и методом завершения
  • корзина с товарами и методом подсчета суммы
  • API-клиент с настройками и методом запроса
  • игра с персонажем, здоровьем и действиями

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

Частые ошибки

Забыть self в методе

class Task:
    def describe():
        return 'задача'

Правильно:

class Task:
    def describe(self):
        return 'задача'

Обращаться к локальной переменной вместо атрибута

def __init__(self, title):
    title = title

Правильно:

def __init__(self, title):
    self.title = title

Создавать класс ради одной строки, где достаточно функции

Хранить все в глобальных переменных и не использовать состояние объекта

Делать слишком большой класс, который отвечает сразу за данные, файлы, сеть, базу и интерфейс

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

Добавьте метод is_done(), который возвращает True или False

Добавьте поле priority

Создайте список из трех задач и выведите только незавершенные

Сделайте класс User с полями name и role

Добавьте методу describe() более понятный текстовый статус

Переделайте словарь задачи в класс Task

Класс в Python помогает объединить данные и действия вокруг одной сущности. __init__ задает начальное состояние, self указывает на текущий объект, методы читают или меняют данные объекта

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

Подписаться
Уведомить о
guest
0 комментариев
Старые
Новые Популярные

Настройки cookie

0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x