如何在python-attrs类中嵌套attrs类列表
解决Python attrs将字典列表转为类结构的优雅实现
错误原因分析
你之前的代码报错,是因为给LooneyToons的characters字段设置converter=Character时,转换器会把整个列表作为参数传给Character的构造函数,但Character需要的是first_name和last_name关键字参数,自然触发参数不匹配的错误。
下面提供两种优雅的实现方式,让你可以直接传入字典列表,由类内部完成转换。
方案一:自定义字段转换器
直接写一个转换器函数,遍历字典列表,将每个字典转为Character实例,再赋值给字段:
from attrs import define, field from typing import List @define(kw_only=True) class Character: first_name: str last_name: str # 自定义转换器:将字典列表转为Character实例列表 def convert_char_list(raw_list: List[dict]) -> List[Character]: return [Character(**item) for item in raw_list] @define class LooneyToons: # 给characters字段绑定自定义转换器 characters: List[Character] = field(factory=list, converter=convert_char_list) # 使用示例 raw_data = {'characters': [ {'first_name': 'Duffy', 'last_name': 'Duck'}, {'first_name': 'Bugs', 'last_name': 'Bunny'}, # 其他角色... ]} # 直接传入字典列表即可 looney_toons = LooneyToons(raw_data['characters']) print(looney_toons)
方案二:使用cattrs库(推荐)
cattrs是attrs官方配套的转换工具,专门用于字典与attrs类之间的双向转换,处理嵌套结构更省心:
- 先安装cattrs:
pip install cattrs
- 实现代码:
from attrs import define from typing import List import cattrs @define(kw_only=True) class Character: first_name: str last_name: str @define class LooneyToons: characters: List[Character] # 初始化转换器 converter = cattrs.GenConverter() # 使用示例 raw_data = {'characters': [ {'first_name': 'Duffy', 'last_name': 'Duck'}, {'first_name': 'Bugs', 'last_name': 'Bunny'}, # 其他角色... ]} # 直接将整个原始字典转为LooneyToons实例 looney_toons = converter.structure(raw_data, LooneyToons) print(looney_toons) # 如果只想传入raw_data['characters'],也可以这样: looney_toons = LooneyToons(converter.structure(raw_data['characters'], List[Character]))
cattrs会自动识别嵌套的List[Character]类型,递归将每个字典转为对应类实例,无需手动遍历,适合更复杂的嵌套结构场景。
内容的提问来源于stack exchange,提问作者brillenheini
相关产品推荐
相关产品推荐

