数据类 dataclass
用 @dataclass 替代手写 __init__、field 默认值、冻结实例
dataclasses 数据类
Python 3.7+ 引入的 dataclass 装饰器,让你用更少代码定义数据类。
学完本章你将掌握: 基本用法、默认值、不可变、field 选项。
一、普通类 vs dataclass
python
# 普通类:需要手写 __init__ __repr__ __eq__ ...
class Person_old:
def __init__(self, name, age):
self.name, self.age = name, age
# dataclass:一行装饰器搞定
from dataclasses import dataclass
@dataclass
class Person:
name: str
age: int
p1 = Person("小明", 20)
p2 = Person("小明", 20)
print(p1) # Person(name='小明', age=20)
print(p1 == p2) # True(自动生成 __eq__)
二、默认值与字段
python
@dataclass
class Student:
name: str
age: int
grade: str = "一年级" # 有默认值的字段
scores: list[int] = None # ⚠️ 可变默认值要用 field
# ⚠️ 可变默认值用 field(default_factory=...)
from dataclasses import field
@dataclass
class Student:
name: str
scores: list[int] = field(default_factory=list)
s1 = Student("小明")
s1.scores.append(90)
s2 = Student("小红")
s2.scores.append(85)
print(s1.scores) # [90](不会互相影响!)
三、不可变数据类
python
@dataclass(frozen=True)
class Point:
x: int
y: int
p = Point(10, 20)
# p.x = 30 # ❌ FrozenInstanceError
四、field 常用参数
python
@dataclass
class Config:
name: str
timeout: int = field(default=30, metadata={"unit": "秒"})
debug: bool = field(default=False, repr=False) # repr 中隐藏
五、实战对比
python
# 不用 dataclass(~15 行)
class Task:
def __init__(self, title, done=False, priority=0):
self.title, self.done, self.priority = title, done, priority
def __repr__(self): return f"Task({self.title!r})"
def __eq__(self, o): return (self.title,self.done)==(o.title,o.done)
# 用 dataclass(~5 行)
@dataclass
class Task:
title: str
done: bool = False
priority: int = 0
小结
@dataclass自动生成__init____repr____eq__- 可变默认值用
field(default_factory=list) frozen=True创建不可变数据类- 相比 namedtuple,dataclass 更灵活