Что такое dataclass?
dataclass — это декоратор, введенный в Python 3.7, который автоматически генерирует специальные методы (такие как __init__, __repr__, __eq__ и другие) для классов, которые в основном служат контейнерами для данных. Это избавляет от необходимости писать много шаблонного кода.
Использование dataclass в Python значительно упрощает работу с классами, предназначенными для хранения данных. Вместо того чтобы вручную определять методы __init__, __repr__, __eq__ и другие, достаточно просто объявить поля данных, а dataclass автоматически сгенерирует необходимый код. Это не только делает классы более лаконичными и понятными, но и улучшает читаемость кода, так как акцент смещается на данные, а не на техническую реализацию. Кроме того, автоматически сгенерированный код снижает вероятность ошибок, которые могут возникнуть при ручном написании.
Как использовать dataclass?
Для начала, тебе нужно импортировать декоратор dataclass из модуля dataclasses:
Затем ты помечаешь класс декоратором @dataclass, и определяешь поля данных, как обычные переменные класса с аннотациями типов:
В этом примере, Point — это dataclass, которая имеет два поля: x и y, оба целого типа. dataclass автоматически создаст: * Конструктор __init__, позволяющий создавать экземпляры класса, например Point(1, 2). * __repr__, возвращающий строковое представление объекта, например Point(x=1, y=2). * __eq__, позволяющий сравнивать объекты, например Point(1, 2) == Point(1, 2).
Пример простого использования
Варианты dataclass
dataclass предоставляет несколько параметров для настройки поведения:
- init: Если True (по умолчанию), генерируется метод __init__. Если False, метод __init__ не создается.
- repr: Если True (по умолчанию), генерируется метод __repr__. Если False, метод __repr__ не создается.
- eq: Если True (по умолчанию), генерируется метод __eq__. Если False, метод __eq__ не создается.
- order: Если True, генерируются методы сравнения (__lt__, __le__, __gt__, __ge__). По умолчанию False.
- unsafe_hash: Если False (по умолчанию), метод __hash__ не генерируется. Если True, метод __hash__ будет сгенерирован, а dataclass станет хешируемым.
- frozen: Если True, экземпляры класса будут неизменяемыми (read-only). По умолчанию False.
Примеры использования параметров
- Отключаем метод __repr__ и делаем класс неизменяемым
2. Устанавливаем порядок, добавляем метод hash и делаем класс неизменяемым
Значения по умолчанию
Ты можешь задавать значения по умолчанию для полей:
При создании экземпляра класса, если значения не переданы, будет использовано значение по умолчанию.
Использование dataclass с изменяемыми типами
Будь осторожен при использовании изменяемых типов данных (списки, словари) в качестве значений по умолчанию. Они будут созданы только один раз и будут использоваться всеми экземплярами класса:
В примере выше изменения в bad1.items также отображаются в bad2.items. Это происходит из-за того, что оба экземпляра класса используют один и тот же список по умолчанию.
Чтобы этого избежать, используй dataclasses.field и default_factory:
В этом случае default_factory=list создаст новый пустой список для каждого нового экземпляра класса.
dict(), __dir__() и другие особенности dataclass.
dict() напрямую не работает с экземплярами dataclass. Для преобразования в словарь нужно использовать ручные способы или сторонние библиотеки.
__dir__() возвращает список всех атрибутов и методов объекта, включая сгенерированные dataclass методы и поля.
__dataclass_fields__ и __dataclass_params__ предоставляют метаданные о полях и параметрах dataclass.
1. dict() в контексте dataclass
- Нет автоматической поддержки: Встроенная функция dict() напрямую не работает с экземплярами dataclass, как с обычными словарями. Если ты попытаешься вызвать dict(instance_of_dataclass), то получишь ошибку TypeError: cannot convert dictionary update sequence element #0 to a sequence.
- Преобразование в словарь: Чтобы преобразовать экземпляр dataclass в словарь, нужно сделать это вручную или воспользоваться сторонней библиотекой. Вот как это можно сделать вручную:
- Почему так? dataclass в первую очередь предназначен для представления данных в виде классов. Хотя данные и хранятся как атрибуты объекта, dataclass не делает их автоматически доступными как словарь.
2. __dir__() в dataclass
- Возвращает атрибуты: Метод __dir__() возвращает список строк, представляющих имена атрибутов и методов объекта. Для dataclass, __dir__() будет включать:Все определенные поля данных.
Автоматически сгенерированные методы (__init__, __repr__, __eq__, и т.д., в зависимости от настроек).
Любые другие методы, добавленные вручную. - Пример
Полезность: __dir__() может быть полезным для интроспекции - просмотра доступных атрибутов и методов экземпляра dataclass.
3. Другие особенности dataclass
- __dataclass_fields__:Это атрибут класса, который содержит словарь, где ключами являются имена полей dataclass, а значениями – объекты dataclasses.Field.
Этот атрибут позволяет получить метаданные о полях dataclass (например, тип, значение по умолчанию, и т.д.).
__dataclass_params__:
- Это атрибут класса, который хранит информацию о параметрах dataclass (например, init, repr, eq, order, и т.д.).
- Это позволяет получить доступ к настройкам, с которыми был создан dataclass.
- Использование с наследованием: Ты можешь создавать dataclass, наследуясь от других dataclass.
- Использование с typing.NamedTuple: dataclass является более гибкой альтернативой typing.NamedTuple, поскольку позволяет задавать значения по умолчанию, добавлять свои методы, а также делать класс изменяемым или неизменяемым.
Удачи!
👉 GIT
Другие шпаргалки
Удачи!
Канал: 101 игра на python