0

0

Python attrs 库简化数据对象的思路

舞姬之光

舞姬之光

发布时间:2026-02-18 15:56:30

|

776人浏览过

|

来源于php中文网

原创

因为 attrs 支持字段级延迟默认值、更细粒度冻结控制、原生 __attrs_post_init__ 钩子,且兼容 python 3.5;dataclass 在 __post_init__ 中无法安全访问其他字段,字段控制语法也更冗长。

python attrs 库简化数据对象的思路

为什么不用 dataclass 而选 attrs

因为 attrs 在 Python 3.6+ 里能做 dataclass 做不了的事:比如字段级默认值延迟计算、更细粒度的冻结控制、原生支持 __attrs_post_init__ 钩子,且对旧版 Python(如 3.5)仍有支持。如果你项目还在用 3.5 或需要字段初始化后立刻校验/转换,attrs 是更稳的选择。

常见错误现象:dataclass 里写 field(default_factory=lambda: []) 看似可行,但无法在 __post_init__ 中安全访问其他字段——而 attrs__attrs_post_init__ 总能拿到完整实例状态。

  • attrs 默认不生成 __init__ 的字段(如 attr.ib(init=False)),dataclass 必须靠 field(init=False),语义一致但写法略冗
  • 想让某个字段只参与比较不参与哈希?eq=True, hash=False 直接配,dataclass 得靠 field(compare=True, hash=False)
  • attrsconvertvalidator 是声明式内建能力,不用手动塞进 __post_init__

attr.ib 的常用参数组合怎么选

别一上来就全用默认值。字段行为差异主要来自这四个参数的搭配:

  • default=...:静态值,比如 default=None;动态值必须用 factory,比如 factory=list(注意不是 factory=lambda: [],后者每次调用都新建 lambda 对象)
  • converter=...:接收原始输入并转成目标类型,比如 converter=str 或自定义函数,失败抛 ValueError,它在 validator 之前执行
  • validator=...:只校验,不改值,比如 attr.validators.instance_of(int),多个校验器用 attr.validators.and_(...) 组合
  • kw_only=True:强制该字段只能用关键字传参,适合可选配置项,避免位置参数错位

性能影响:所有 converter / validator 都在实例化时同步执行,高频创建对象时要注意函数开销;validator 不触发属性访问,所以不会意外触发 descriptor 的 __get__

立即学习Python免费学习笔记(深入)”;

Python快速入门
Python快速入门

快速学习python书第二版是一本简洁清晰介绍python3的书籍,目标是新学习python 的程序员。这本更新版本囊括了所有python3版本的变化,即python从早期版本到新版本的特性变化 本书一开始用基础但是很有用的程序来传授给读者关于python的核心特性,包括语法,控制流程和数据结构。然后本书使用大型的应用程序包括代码管理,面向对象编程,web开发和转换老版本的python程序到新的版本等等。 忠实于作者的经验十足的开发者的观众,作者仔细检查普通程序特点,同时增加了更多细节关于这些python

下载

冻结对象后还能改字段吗

能,但得绕过保护机制——这不是 bug,是设计如此:frozen=True 只禁用常规赋值(obj.x = 1),不拦 object.__setattr__(obj, 'x', 1)。所以“冻结”本质是防误改,不是绝对不可变。

容易踩的坑:

  • 用了 frozen=True 却在 __attrs_post_init__ 里直接赋值字段,会报 FrozenInstanceError;正确做法是先调 object.__setattr__(self, 'x', value)
  • 继承自 frozen 类的子类,如果没显式写 frozen=True,子类实例反而可修改父类字段——冻结不自动继承
  • attrsevolve() 函数能安全复制并修改字段,比手动绕过 __setattr__ 更推荐

和 Pydantic v2 混用时字段校验谁生效

如果你把 attrs 类当 Pydantic 的 model_config = {'arbitrary_types_allowed': True} 里的字段类型用,校验链是:Pydantic 先走自己的验证逻辑(比如 str 转换、@field_validator),再把结果传给 attrs 实例化——此时 attrsconvertervalidator 仍会执行。

这意味着:

  • 重复校验可能触发两次异常,堆栈难读;建议关闭 Pydantic 对该字段的校验(用 Field(validate_default=False)),交由 attrs 全权处理
  • attrsconverter 返回值若类型不符 Pydantic 预期(比如返回 int 但字段注解是 str),Pydantic 会再转一次,可能出错
  • 最稳妥的做法:只用 attrs 做数据容器,Pydantic 做 API 层入参解析,两者职责隔离

复杂点在于字段级生命周期控制——attrs 的钩子发生在对象构造完成瞬间,Pydantic 的钩子则穿插在解析各层之间,混用时顺序和上下文容易错乱。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

770

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

572

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

254

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

210

2025.08.29

lambda表达式
lambda表达式

Lambda表达式是一种匿名函数的简洁表示方式,它可以在需要函数作为参数的地方使用,并提供了一种更简洁、更灵活的编码方式,其语法为“lambda 参数列表: 表达式”,参数列表是函数的参数,可以包含一个或多个参数,用逗号分隔,表达式是函数的执行体,用于定义函数的具体操作。本专题为大家提供lambda表达式相关的文章、下载、课程内容,供大家免费下载体验。

212

2023.09.15

python lambda函数
python lambda函数

本专题整合了python lambda函数用法详解,阅读专题下面的文章了解更多详细内容。

192

2025.11.08

Python lambda详解
Python lambda详解

本专题整合了Python lambda函数相关教程,阅读下面的文章了解更多详细内容。

58

2026.01.05

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

419

2023.07.18

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

561

2026.02.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.4万人学习

Django 教程
Django 教程

共28课时 | 4.4万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号