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Сообщить о неточности