You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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类之间的双向转换,处理嵌套结构更省心:

  1. 先安装cattrs:
pip install cattrs
  1. 实现代码:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 00:52:52