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 особливо корисні, коли вам потрібні зручні та легко настроювані структури даних з підтримкою методів порівняння та відображення. З іншого боку, у них є свої обмеження: вони не підтримують складну логіку в конструкторі і високу продуктивність.
Sigma Software, що є підрозділом Sigma Software Group, заявила про зміну генерального директора. Компанію очолить…
Microsoft готує додати у Windows 11 новий «легкий» текстовий редактор Edit. Він важить всього 230…
Компанія OpenAI у найближчі тижні планує випустити оновлення для тарифного плану ChatGPT Pro, доступ до…
Керівники компаній часто вводять в оману, розповідаючи, що штучний інтелект лише підвищить продуктивність і не…
Уряд США пропонує до $10 мільйонів за інформацію про місцезнаходження розробника шкідливого програмного забезпечення RedLine…
Google оголосила про оновлення своєї LLM-моделі Gemini 2.5 Pro, яка, за твердженням компанії, стала краще…