Python Glossary English

Python 3.7+dataclassesпонятие

@dataclass

базовый

@dataclass автоматически генерирует __init__, __repr__, __eq__. field() настраивает отдельные поля.

Синтаксис

from dataclasses import dataclass
@dataclass
class Point:
    x: float
    y: float

Поля со значением по умолчанию обязаны идти после полей без него — иначе TypeError ещё на этапе создания класса. Изменяемый дефолт вроде x: list = [] отвергается сразу с ValueError: нужен field(default_factory=list), иначе список был бы общим для всех экземпляров. Аннотации типов здесь лишь разметка, во время выполнения их никто не проверяет: Point("a", "b") создастся спокойно.

Примеры

from dataclasses import dataclass
@dataclass
class Point:
    x: float
    y: float
p = Point(1.0, 2.0)
print(p)  # → Point(x=1.0, y=2.0)
print(p.x, p.y)  # → 1.0 2.0
# __eq__ автоматически
print(Point(1,2) == Point(1,2))  # → True
print(Point(1,2) == Point(1,3))  # → False
from dataclasses import dataclass
from dataclasses import dataclass, field
@dataclass
class Inventory:
    name: str
    items: list = field(default_factory=list)
    count: int = field(default=0, repr=False)
inv = Inventory('store')
inv.items.append('apple')
print(inv)  # → Inventory(name='store', items=['apple'])
from dataclasses import dataclass
from dataclasses import dataclass, field
# frozen=True — неизменяемый
@dataclass(frozen=True)
class ImmutablePoint:
    x: float
    y: float
ip = ImmutablePoint(1,2)
try:
    ip.x = 5  # присваивание во frozen-dataclass запрещено
except Exception as e:
    print(e)  # → cannot assign to field 'x'
from dataclasses import dataclass
from dataclasses import dataclass, field
# __post_init__
@dataclass
class Circle:
    radius: float
    area: float = field(init=False)
    def __post_init__(self):
        import math
        self.area = math.pi * self.radius**2
c = Circle(5)
print(round(c.area, 2))  # → 78.54
from dataclasses import dataclass
from dataclasses import dataclass, field
# order=True — для сравнения
@dataclass(order=True)
class Student:
    grade: int
    name: str
students = [Student(85,'Bob'), Student(90,'Alice')]
print([s.name for s in sorted(students)])  # → ['Bob', 'Alice']
from dataclasses import dataclass
from dataclasses import dataclass, field
# Наследование dataclass
@dataclass
class Animal:
    name: str
    sound: str
@dataclass
class Dog(Animal):
    breed: str
d = Dog('Rex', 'Woof', 'Lab')
print(d)  # → Dog(name='Rex', sound='Woof', breed='Lab')

См. также

Открыть в полном глоссарииdocs.python.orgСообщить о неточности