Python3.7 dataclass 介绍与使用指南

根据 PEP 和文档和自己的实验写了一篇大概的介绍。包括了继承关系的处理,hook,gotchas 等,能让你快速上手和避免陷阱。

https://www.kawabangga.com/posts/2959


Python3.7 dataclass 介绍与使用指南
1 回复

Python 3.7引入的dataclass装饰器是个好东西,它帮你自动生成__init____repr____eq__这些样板方法,写数据类再也不用那么啰嗦了。

基本用法很简单,用@dataclass装饰一个类,在类里定义类型注解的字段就行:

from dataclasses import dataclass

@dataclass
class Point:
    x: float
    y: float

p = Point(1.5, 2.5)
print(p)  # 输出: Point(x=1.5, y=2.5)

默认情况下字段是可变的,你可以用frozen=True让它不可变:

@dataclass(frozen=True)
class ImmutablePoint:
    x: float
    y: float

p = ImmutablePoint(1.0, 2.0)
# p.x = 3.0  # 这行会报错:FrozenInstanceError

field()函数可以控制更多细节,比如设置默认值、排除比较等:

from dataclasses import dataclass, field
from typing import List

@dataclass
class User:
    name: str
    age: int = 18  # 默认值
    tags: List[str] = field(default_factory=list)  # 可变默认值要用default_factory
    _id: int = field(init=False, repr=False)  # 不包含在__init__和__repr__中
    
    def __post_init__(self):
        self._id = hash(self.name + str(self.age))

user = User("Alice")
print(user)  # 输出: User(name='Alice', age=18, tags=[])

dataclass还支持继承,但要注意父类的字段顺序:

@dataclass
class Base:
    x: int

@dataclass
class Derived(Base):
    y: int

d = Derived(1, 2)  # 先父类字段,后子类字段

它还能和asdict()astuple()配合方便地转换数据:

from dataclasses import asdict, astuple

point = Point(1, 2)
print(asdict(point))  # {'x': 1, 'y': 2}
print(astuple(point))  # (1, 2)

总结:用dataclass写数据类能省不少事。

回到顶部