一、field()的全部参数field()用于对字段进行精细控制。参数如下from dataclasses import dataclass, field dataclass class Example: a: int field( default0, # 默认值 default_factoryNone, # 默认工厂与 default 二选一 initTrue, # 是否出现在 __init__ 参数中 reprTrue, # 是否出现在 __repr__ 中 compareTrue, # 是否参与 __eq__ 比较 hashNone, # 是否参与 __hash__None 表示继承 compare metadataNone, # 附加元数据 kw_onlyFalse # 是否强制关键字参数Python 3.10 )1.defaultvsdefault_factory参数适用类型说明default不可变对象数字、字符串、元组、Nonedefault_factory可变对象或动态值列表、字典、集合、函数调用# 不可变默认值直接用 default count: int field(default0) # 可变默认值必须用 default_factory items: list field(default_factorylist) # 动态默认值用工厂函数 created_at: str field(default_factorylambda: datetime.now().isoformat())2.initFalse不参与初始化dataclass class User: name: str age: int # 不参与 __init__只能通过其他方式赋值 created_at: str field(default, initFalse) u User(Alice, 25) # 不用传 created_at # u User(Alice, 25, 2024) # 会报错适用场景字段由内部逻辑填充不需要外部传入。3.reprFalse隐藏敏感字段dataclass class User: name: str password: str field(reprFalse) # 不出现在 __repr__ 中 u User(Alice, secret123) print(u) # User(nameAlice)密码不会打印适用场景密码、Token 等敏感信息。4.compareFalse不参与比较dataclass class User: id: int name: str timestamp: float field(compareFalse) # 不参与 比较 u1 User(1, Alice, 100.0) u2 User(1, Alice, 200.0) print(u1 u2) # Truetimestamp 不参与比较适用场景时间戳、缓存字段等不需要比较的字段。5.kw_onlyTrue强制关键字参数Python 3.10dataclass class Point: x: int y: int field(kw_onlyTrue) # 必须用 y 传 p Point(1, y2) # 正确 # p Point(1, 2) # 报错适用场景参数多时强制关键字传参避免顺序错误。6.metadata附加元数据dataclass class Product: name: str field(metadata{description: 商品名, max_length: 100}) price: float field(metadata{unit: 元}) # 获取元数据 print(Product.__dataclass_fields__[name].metadata) # {description: 商品名, max_length: 100}适用场景配合序列化库、ORM、文档生成工具使用。二、__post_init__后置初始化__init__自动生成后如果需要在初始化后做额外处理用__post_init__。dataclass class Rectangle: width: float height: float area: float field(initFalse) # 不通过 __init__ 传 def __post_init__(self): self.area self.width * self.height r Rectangle(3, 4) print(r.area) # 12.0执行顺序自动生成的__init__赋值所有字段__post_init__被调用完成初始化常用场景计算派生字段数据校验类型转换dataclass class User: name: str age: int def __post_init__(self): if self.age 0: raise ValueError(年龄不能为负数) self.name self.name.strip()三、frozenTrue不可变数据类frozenTrue让实例创建后不能修改类似tuple。dataclass(frozenTrue) class Point: x: int y: int p Point(1, 2) # p.x 3 # FrozenInstanceError1.frozenTrue带来的特性特性说明不可修改修改字段抛FrozenInstanceError可哈希自动生成__hash__可作为字典键线程安全不可变对象天生线程安全p1 Point(1, 2) p2 Point(1, 2) d {p1: 原点} # 可作为字典键 print(d[p2]) # 原点2.frozenTrue的__post_init__陷阱在frozenTrue时__post_init__里不能用self.x ...要用object.__setattr__dataclass(frozenTrue) class Circle: radius: float area: float field(initFalse) def __post_init__(self): # self.area ... # FrozenInstanceError object.__setattr__(self, area, 3.14 * self.radius ** 2)3. 适用场景场景说明配置对象创建后不应修改值对象如坐标、金额、颜色字典键需要可哈希多线程共享避免竞态条件四、orderTrue支持排序orderTrue自动生成、、、方法按字段顺序比较。dataclass(orderTrue) class Student: score: int name: str students [ Student(85, Bob), Student(92, Alice), Student(78, Charlie), ] students.sort() for s in students: print(s) # Student(score78, nameCharlie) # Student(score85, nameBob) # Student(score92, nameAlice)比较规则按字段声明顺序逐字段比较。dataclass(orderTrue) class Item: price: float name: str # 先比 priceprice 相同再比 name隐藏字段不参与排序dataclass(orderTrue) class Item: price: float name: str field(compareFalse) # 不参与排序五、dataclass的继承dataclass支持继承子类会合并父类的字段。dataclass class Person: name: str age: int dataclass class Student(Person): school: str grade: int s Student(Alice, 18, 清华, 3) print(s) # Student(nameAlice, age18, school清华, grade3)1. 字段顺序规则子类的字段会追加到父类字段后面。dataclass class A: x: int dataclass class B(A): y: int # B 的字段顺序x, y2. 默认值冲突问题如果父类有默认值子类字段必须有默认值dataclass class A: x: int 0 dataclass class B(A): y: int # 报错y 没有默认值但父类 x 有默认值原因Python 要求有默认值的字段不能在无默认值字段之后。解决方案给子类字段也加默认值或用kw_onlyTrue。dataclass class B(A): y: int 0 # # 或者 dataclass class C(A): y: int field(kw_onlyTrue) # 强制关键字参数3.frozen的继承frozenTrue和frozenFalse不能混用dataclass(frozenTrue) class A: x: int dataclass(frozenFalse) # 报错 class B(A): y: int规则子类的frozen必须与父类一致。dataclassvs Pydantic vs attrs维度dataclassPydanticattrs来源标准库第三方第三方数据校验无强需配置序列化无内置 JSON无性能快中快可变性frozen控制可配置可配置类型转换无自动需配置学习成本低中中适用场景内部数据类API、配置、验证高性能、复杂需求
阅读完成 · 觉得有帮助?