首页电脑使用嵌套式叙事结构 嵌套try catch

嵌套式叙事结构 嵌套try catch

圆圆2025-08-06 00:00:52次浏览条评论

attrs 与 cattrs:优雅处理嵌套数据结构的教程本教程详细阐述了如何使用 Python 的 attrs 和 cattrs 库来高效处理检索的数据结构,特别是包含字典列表的复杂数据转换为 attrs 定义的类实例列表。文章将解释 attrs 内置转换器的视觉,并演示 cattrs 如何通过其强大的格式化功能,自动且高效地完成从原始字典数据到复杂 attrs 对象的映射,从而简化代码并提高可维护性理解。 attrs 中的数据建模

在 python 中,attrs 库提供了一种简洁而强大的方式来构造定义数据类,它通过装饰器和类型提示极大地简化了样板代码。当我们需要将外部数据(如 json 或字典)映射到这些定义好的 attrs 时类时,通常会遇到挽回结构的处理问题。

考虑一个场景,我们有一组角色数据,每个角色包含姓名信息,而这些角色共同构成一个团队。数据结构如下所示:data_source = { quot;charactersquot;: [ {quot;first_namequot;: quot;Duffyquot;, quot;last_namequot;: quot;Duckquot;}, {quot;first_namequot;: quot;Bugsquot;, quot;last_namequot;: quot;Bunnyquot;}, # ... 更多角色]}登录后复制

我们希望将其为 attrs 类实例:from attrs import Define,fieldfrom Typing import List@define(kw_only=True)class Character:first_name:str last_name:str@defineclass LooneyToons:characters:List[Character] = field(factory=list)#最初定义,稍后解释为何取消转换converter登录后复制attrs在转换器的范围内

attrs提供了转换器参数,用于在赋值时对输入值进行转换。例如,some_field:int = field(converter=int)可以确保输入值被为整数。

然而,在处理列表中的复杂对象转换时,直接使用 converter=Character 会遇到问题:# 错误示例:直接将 Character 作为 List[Character] 的 converter@defineclass LooneyToons_Problematic:characters: List[Character] = field(factory=list,converter=Character)# 尝试使用:# LooneyToons_Problematic(characters=data_source['characters'])# 这将导致 TypeError: Character.__init__() 需要 1 个位置参数,但给出了 2 个位置参数,登录后复制

这个错误的原因是,attrs 的转换器需要一个函数,该函数接收单个值并将其转换为目标类型。当我们将其确认一个 List[Character] 字段时,attrs 会尝试将整个列表 data_source['characters'] 作为参数传递给 Character 类的结构化函数(即 Character.__init__),这显然是不正确的,因为 Character期望的是名字和姓氏 这样的关键字参数,是一个字典列表。手动转换不足之处而不是解决方案是遍历手动列表,并为每个字典创建字符实例:#手动转换示例looney_tunes_instance = LooneyToons(characters=[Character(**x) for x in data_source['characters']])print(looney_tunes_instance)#输出: LooneyToons(characters=[Character(first_name='Duffy',last_name='Duck'),...])登录后

这种方法虽然有效,但在以下情况下不够扩展慢或高效:样板代码重复:错误需要转换列表时,都需要编写类似的列表推导式。类的实例化过程中自动完成,需要外部手动处理。引入cattrs:自动化复杂数据结构转换

为了更优雅、自动化地处理 attrs 类与复杂数据格式(如字典、列表)之间的转换,cattrs 库应运而生。cattrs 是一个强大的转换工具,专门用于解决在 Python 对象和原始数据类型之间进行格式化(结构化)和非结构化(非结构化)。它通过利用类型提示,能够智能解析复杂的数据结构并自动执行深层。

使用 cattrs 上述问题非常简单:

删除参数:在LooneyToons 类的字符字段定义中,我们不再需要转换器参数。cattrs 将根据类型提示列表[字符]自动推断出正确的转换逻辑。

使用cattrs.struct:调用cattrs.struct()函数,将原始字典数据和目标属性类作为参数确定。

以下是完整的cattrs方案代码:fromtypesimportListfromattrsimportdefine,fieldfromcattrsimportstruct#导入cattrs的结构函数#解决样本数据data_source={quot;charactersquot;:[{quot;first_namequot;:quot;Duffyquot;,quot;last_namequot;:quot;Duckquot;},{quot;first_namequot;: “Bugs”;,“last_name”;:“Bunny”;},{“first_name”;:“Sylvester”;,“last_name”;:“Pussycat”;},{“first_name”;:“Elmar”;,“last_name”;:“Fudd”;},{“first_name”; “Tweety”;,“last_name”;: ”Bird”;}, {“first_name”;: “Sam”;, “last_name”;: “Yosemite”;}, {“first_name”;: “Wile E.”;, “last_name”;: “Coyote”;}, {“first_name”;: “Road”;, “last_name”;: “Runner”;}, ]}# 定义内部的字符类@define(kw_only=True)class 字符:first_name:str last_name:str#定义外部的LooneyToons转换类,注意去掉了转换器参数@defineclass LooneyToons:字符:List[Character] = field(factory=list)#使用cattrs.struct进行looney_tunes_instance = Structure(data_source, LooneyToons)print(looney_tunes_instance)#预期输出:# LooneyToons(characters=[Character(first_name='Duffy',last_name='Duck'),Character(first_name='Bugs',last_name='Bunny'),Character(first_name='Sylvester',last_name='Pussycat'),C

字符(first_name='Elmar',last_name='Fudd'), 字符(first_name='Tweety',last_name='Bird'), 字符(first_name='Sam',last_name='Yosemite'), 字符(first_name='Wile E.',last_name='Coyote'), 字符(first_name='Road',last_name='Runner')])#验证类型print(isinstance(looney_tunes_instance.characters[0],Character)) # True登录后复制

在这个例子中,cattrs.struct(data_source, LooneyToons) 会执行以下操作:它检查LooneyToons的类型提示。发现字符字段被标记为List[Character]。cattrs 遍历 data_source['characters']中的每一个字典。对于每一个字典,cattrs知道它需要将其转换为一个字符实例,因此它会自动调用 Character(**dict_item) 来创建对象。最终,所有创建的Character实例被收集到一个列表中,并赋值给looney_tunes_instance.characters。总结与注意事项attrs的转换器与cattrs.structs的转换:attrs内置的转换器适用于简单的、单值到单值的。当需要处理对象、列表或复杂的类型映射时,cattrs是更专业、更强大的选择。类型提示的重要性:cattrs严重依赖于Python的类型提示来理解如何进行数据转换。确保你的attrs类字段都带有准确的类型提示。灵活与扩展:cattrs提供了注册自定义转换器转换(register_struction_hook)的能力,这使得它能够处理各种非标准的数据类型或特殊的转换逻辑,进一步增强了其灵活性。减少样板代码:通过使用cattrs,你可以将数据的复杂逻辑从业务代码中解耦出来,使得attrs类的定义更加纯粹,只关注数据本身结构。

通过结合attrs定义清晰的数据模型和cattrs 自动化数据映射,开发者可以更高效、更优雅地处理Python中的复杂数据结构,显着提高代码的约束性、可维护性和健壮性。

以上就是attrs 与 cattrs:优雅预览处理数据结构教程的详细文章,内容更多请关注乐哥常识网其他相关!

attrs 与 ca
ECShop小京东集成Spark方法 ecshopx
相关内容
发表评论

游客 回复需填写必要信息