文章
@dataclass概述
@dataclass 是 Python 标准库 dataclasses 模块提供的类装饰器,用于简化定义纯数据容器类的样板代码
@dataclass 概述#
@dataclass 是 Python 标准库 dataclasses 模块提供的类装饰器,用于简化定义纯数据容器类的样板代码。
from dataclasses import dataclass
@dataclass
class MyClass:
field1: int
field2: str
- Python 3.7+ 内置支持,无需额外安装。
- Python 3.6 可通过
pip install dataclasses安装兼容包。
核心功能#
- **自动生成 **
__init__根据字段定义自动创建构造函数。 - **自动生成 **
__repr__提供可读性强的字符串表示,便于调试和日志。 - **自动生成 **
__eq__比较实例字段值是否相等。 - 可选排序方法 (
order=True) 生成__lt__,__le__,__gt__,__ge__方法,实现实例间比较。 - 可选不可变实例 (
frozen=True) 生成只读属性,禁止修改。 - 支持默认值
- 普通默认值:
age: int = 18 - 默认工厂(可变类型):
field(default_factory=list)
- 普通默认值:
- 关键字-only (
kw_only=True, Python 3.10+) 强制字段只能用关键字参数初始化。 - **使用 **
__slots__(slots=True, Python 3.10+) 自动生成__slots__,节省内存并禁止动态新增属性。
参数详解#
| 参数 | 类型 | 作用 |
| `init` | bool | 是否生成 `__init__` (默认 `True`) |
| `repr` | bool | 是否生成 `__repr__` (默认 `True`) |
| `eq` | bool | 是否生成 `__eq__` (默认 `True`) |
| `order` | bool | 是否生成排序方法(`__lt__` 等),依赖于 `eq=True`,默认 `False` |
| `unsafe_hash` | bool | 即使 `frozen=False` 也生成 `__hash__` |
| `frozen` | bool | 实例是否不可变(字段赋值后禁止修改),默认 `False` |
| `kw_only` | bool | 强制所有字段仅能以关键字参数形式传入,Python 3.10+,默认 `False` |
| `slots` | bool | 是否生成 `__slots__` 以替代 `__dict__`,节省内存并禁止动态属性,Python 3.10+,默认 `False` |
使用示例#
1. 简单数据类#
from dataclasses import dataclass
@dataclass
class Point:
x: int
y: int
p = Point(3, 4)
print(p) # Point(x=3, y=4)
2. 默认值 & 可变默认#
from dataclasses import dataclass, field
@dataclass
class User:
name: str
age: int = 18
tags: list[str] = field(default_factory=list)
u = User(name="Alice")
u.tags.append("admin")
print(u) # User(name='Alice', age=18, tags=['admin'])
3. 排序实例#
from dataclasses import dataclass
@dataclass(order=True)
class Version:
major: int
minor: int
patch: int
print(Version(1,2,0) < Version(1,3,5)) # True
4. 不可变 & slots#
from dataclasses import dataclass
@dataclass(frozen=True, slots=True)
class Config:
host: str
port: int
cfg = Config(host="localhost", port=8080)
# cfg.port = 9090 # 会抛出 FrozenInstanceError
# cfg.new_attr = ... # 会抛出 AttributeError
何时使用#
- 定义 简单数据容器,不含复杂业务逻辑时。
- 替代手写大量样板代码的场景,提高可读性与开发效率。
- 需要 比较、打印 或 序列化 时,自动方法大大简化实现。