Python高级应用系列(十一):数据类与模型——dataclass、attrs、Pydantic深度对比

张开发
2026/4/21 18:32:09 15 分钟阅读

分享文章

Python高级应用系列(十一):数据类与模型——dataclass、attrs、Pydantic深度对比
标签:Python | dataclass | attrs | Pydantic | 数据模型 | 序列化字数:约 4000 字建议阅读时间:12 分钟前言在 Python 中表示"带字段的数据结构"这件事,从未如此优雅。早期的namedtuple、手写__init__+__repr__+__eq__的 boilerplate 代码,到如今标准库的dataclass、社区宠儿attrs,以及 validation 之王Pydantic,选择越来越丰富,但什么时候用哪个,却让人犯难。本文系统对比这三种主流方案,从基础用法到高级特性,帮你做出正确的技术选型。一、为什么需要数据类传统 Python 类的问题:class Point: def __init__(self, x, y): self.x = x self.y = y def __repr__(self): return f"Point(x={self.x}, y={self.y})" def __eq__(self, other): if not isinstance(other, Point): return False return self.x == other.x and self.y == other.y需要手写大量__repr__、__eq__等样板代码。数据类正是为了解决这个问题。二、dataclass(Python 3.7+)2.1 基础用法from dataclasses import dataclass from typing import Optional @dataclass class Point: x: float y: float color: str = "black" # 带默认值 p = Point(1.0, 2.0) print(p) # Point(x=1.0, y=2.0, color='black') print(p == Point(1.0, 2.0)) # True(自动生成 __eq__)2.2 dataclass 字段选项from dataclasses import dataclass, field from typing import List @dataclass class Config: name: str port: int = 8080 enabled: bool = True # 工厂函数:用于 mutable 默认值(避免共享问题) tags: List[str] = field(default_factory=list) # 比较时忽略某字段 secret: str = field(compare=False, repr=False)2.3frozen=True:不可变对象from dataclasses import dataclass @dataclass(frozen=True) class RGB: r: int g: int b: int color = RGB(255, 0, 128) # color.r = 0 # FrozenInstanceError: 无法修改2.4__post_init__:初始化后处理from dataclasses import dataclass, field @dataclass class Circle: radius: float # 派生字段:在 __post_init__ 中计算 area: float = field(init=False) def __post_init__(self): import math self.area = m

更多文章