Data classes в Python: де варто застосовувати декоратор dataclass
Python відомий тим, що це мова програмування з підтримкою об’єктно-орієнтованих парадигм, де класи є одним з основних інструментів для роботи з даними та функціоналом. Але в реальній роботі часто доводиться писати звичайний клас, завданням якого має бути лише зберігання даних, без будь-якої премудрої логіки. Щоб уникнути шаблонності в коді та скоротити випадки дублювання, у версії 3.7 мові Python з’явилася нова можливість – Data Classes.
До появи Data Classes кодерам доводилося вручну описувати прості класи Python для представлення сутностей з кількома атрибутами. Наприклад:
class Person: def __init__(self, name: str, age: int): self.name = name self.age = age def __repr__(self): return f"Person(name={self.name}, age={self.age})"
У цьому фрагменті ми вручну створюємо конструктор і метод для рядкового представлення об’єкта. Але при додаванні нових атрибутів або методів код швидко розростається, стаючи менш зручним та підтримуваним. Data Classes автоматизують цей процес.
Щоб створити Data Class, потрібно вказати декоратор @dataclass з модуля dataclasses. Розглянемо простий приклад:
від dataclasses import dataclass @dataclass class Point: x: int y: int
У цьому фрагменті Point є класом, що містить атрибути x та y. Завдяки декоратору @dataclass, Python самостійно створює конструктор __init__(), метод __repr__() та інші корисні методи.
Тепер можна створити об’єкт цього класу:
point = Point(10, 20) print(point) # Output: Point(x=10, y=20)
Декоратор @dataclass автоматично створює метод __init__(), який ініціалізує атрибути об’єкта:
@dataclass class Person: name: str age: int p = Person("Laura", 20) print(p) # Output: Person(name='Laura', age=20)
Data Classes самі генерують рядкове представлення для екземплярів класу, що дуже корисно при налагодженні:
print(repr(p)) # Output: Person(name='Laura', age=20)
Data Classes генерують метод __eq__(), який може порівняти об’єкти між собою виходячи з їхніх атрибутів. Ось один приклад:
p1 = Person("Laura", 20) p2 = Person("Laura", 20) print(p1 == p2) # Output: True
Оскільки обидва об’єкти мають однакові значення атрибутів, вони вважаються рівними.
Об’єкти, створені за допомогою Data Classes, вважаються мутабельними (змінними) за замовчанням. Але ви можете створити незмінний клас, якщо встановите параметр frozen=True. Тепер, якщо хтось спробує змінити атрибут після створення об’єкта, з’явиться помилка:
@dataclass(frozen=True) class ImmutablePoint: x: int y: int point = ImmutablePoint(1, 2) # point.x = 10 # Помилка: Cannot assign to field 'x'
Data Classes здатні автоматично створювати методи порівняння (__lt__(), __le__(), __gt__(), і __ge__()), якщо буде вказано параметр order=True:
@dataclass(order=True) class Item: name: str price: float item1 = Item("Apple", 1.0) item2 = Item("Banana", 2.0) print(item1 < item2) # Output: True
Використання такого параметра стане в нагоді, коли потрібно порівняти та сортувати об’єкти класу.
Data Classes підтримує кілька корисних параметрів, які можуть передаватися в декоратор @dataclass:
1. init=False: Якщо ви не хочете, щоб для якогось поля автоматично створювався конструктор, його можна вимкнути. Розглянемо наступний код:
@dataclass class Product: name: str price: float = 0.0 in_stock: bool = False discount: float = field(init=False, default=0.1)
У цьому фрагменті для атрибута конструктор автоматично не згенерується.
2. repr=False: Ця властивість виключає поле з рядкового представлення об’єкта:
@dataclass class PrivateData: id: int secret: str = field (repr = False) pd = PrivateData(1, "top_secret") print(pd) # Output: PrivateData(id=1)
3. default_factory: Дає можливість задавати значення за замовчуванням за допомогою функції:
from typing import List @dataclass class DataContainer: items: List[int] = field(default_factory=list) container = DataContainer() print(container.items) # Output: []
Data Classes допускає наслідування. Тому ви можете розширювати класи, додавати нові атрибути або методи. Однак, якщо ви успадкуєте від іншого класу з @dataclass, потрібно враховувати порядок ініціалізації:
@dataclass class Employee(Person): employee_id: int e = Employee("Bob", 25, 1234) print(e) # Output: Employee(name='Bob', age=25, employee_id=1234)
Тут клас Employee отримує наслідування від Person та додає нове поле employee_id.
Data Classes часто порівнюються з іншими способами роботи з даними Python, такими як іменовані кортежі (namedtuple) і словники. Розглянемо коротке порівняння:
namedtuple:
словники:
Data Classes забезпечують баланс між простотою і гнучкістю, роблячи їх кращими для структурованих даних.
Незважаючи на цілу низку очевидних переваг Data Classes у Python, можуть виникнути ситуації, коли їх використання не зовсім підходить. Ось кілька випадків, коли краще не застосовувати Data Classes:
Data Classes — це потужний спосіб роботи з класами, які використовуються для зберігання даних. Вони значно спрощують написання коду, скорочуючи число шаблонних методів, підвищуючи читаність і продуктивність. Data Classes особливо корисні, коли вам потрібні зручні та легко настроювані структури даних з підтримкою методів порівняння та відображення. З іншого боку, у них є свої обмеження: вони не підтримують складну логіку в конструкторі і високу продуктивність.
Резиденти Дія.City сплатили до бюджету понад 8 млрд грн податків в І кварталі 2025 року.…
У Китаї закликають офісних працівників не працювати надто багато — держава сподівається, що вільний час…
Експерти звертають увагу на тривожну тенденцію: люди все частіше використовують ChatGPT, щоб визначити місцезнаходження, зображене…
Компанія JetBrains випустила нову версію мультимовного середовища розробки IntelliJ IDEA 2025.1. Оновлена IDE отримала численні…
Платформа обміну миттєвими повідомленнями Discord впроваджує функцію перевірки віку за допомогою сканування обличчя. Зараз вона…
Wikipedia намагається захистити себе від тисяч різноманітних ботів-скрейперів, які сканують дані цієї платформи для навчання…