📢 欢迎来到万事技术论坛!本站仅讨论合法编程技术话题,严禁外挂/作弊/黑产/盗版内容,违者封号。

精华别再手写 __init__ 了:dataclass 实用技巧

lin_dev 活跃会员

dataclass 用久了会发现它不只是省几行代码。

基础

from dataclasses import dataclass, field

@dataclass
class User:
    name: str
    age: int = 0
    tags: list = field(default_factory=list)   # 可变默认值必须这样写

直接写 tags: list = [] 会报错,因为所有实例共享同一个列表——这是可变默认参数的经典坑。default_factory 每次调用生成新对象。

常用参数

@dataclass(order=True, frozen=True, slots=True)
class Point:
    x: float
    y: float
  • order=True:自动生成 __lt__ 等,可以直接排序比较
  • frozen=True:不可变,可作字典 key、可哈希
  • slots=True:生成 __slots__,省内存(3.10+)

只想要不可变但需要一个可变的缓存字段

frozen=True 时所有字段都不可改,如果某字段只是内部缓存,用 field(init=False):

@dataclass(frozen=True)
class Config:
    path: str
    _cache: dict = field(default_factory=dict, init=False, repr=False, compare=False)

init=False 不进构造函数,repr=False 不打印,compare=False 不参与相等比较。

继承时字段顺序

父类有默认值的字段,子类字段也必须有默认值,否则 TypeError: non-default argument follows default argument。

楼主 · 2026-09-28 13:21 · 浏览 4
登录 后即可参与回复。