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

如何在YAML中使用自定义对象作为字典键?

问题与解决方案:用YAML配置以自定义类实例为键的字典

问题背景

定义如下Python类:

class A:
    def __init__(self, a=None, b=None):
        self.a = a
        self.b = b

需要创建一个以该类实例为键的字典,示例代码如下:

m = {
    A(a=1): 2,
    A(a=3, b=4): 5,
    A(b=6): 7
}

尝试用YAML配置时,以下写法出现duplicated mapping key错误:

{ a: 1 } : 2
{ a: 3, b: 4 } : 5
{ b: 6 } : 7

已知可以用列表形式编写,但希望保留命名字段,同时想了解其他可选的配置格式。


YAML的正确实现方式

YAML解析器会将未包裹的映射结构({a:1})视为普通映射,直接作为键时容易触发语法歧义,导致重复键错误。可以通过两种方式解决:

1. 给映射键添加引号

将映射结构字符串化,用引号包裹作为键:

"{ a: 1 }": 2
"{ a: 3, b: 4 }": 5
"{ b: 6 }": 7

注意:读取后得到的键是字符串类型,需要在Python中额外处理,比如用ast.literal_eval解析字符串为字典,再通过A(**dict_data)转换为类实例。

2. 使用YAML的块式映射键语法

YAML支持用?标记键的起始,后续用块式结构定义键内容:

?
  a: 1
: 2
?
  a: 3
  b: 4
: 5
?
  b: 6
: 7

这种写法符合YAML规范,不会出现语法错误。读取时,每个?后的块会被解析为Python字典,直接通过A(**key_dict)即可转换为A类的实例。


其他可选配置格式

如果YAML的处理方式不够顺手,还可以考虑以下格式:

  • JSON:JSON的键只能是字符串,但可以将类实例的参数结构序列化为JSON字符串作为键:

    {
      "{\"a\": 1}": 2,
      "{\"a\": 3, \"b\": 4}": 5,
      "{\"b\": 6}": 7
    }
    

    读取后用json.loads解析键字符串为字典,再转换为A实例。

  • TOML:TOML同样只支持字符串键,可将参数结构写成字符串形式:

    "{a = 1}" = 2
    "{a = 3, b = 4}" = 5
    "{b = 6}" = 7
    

    读取后需要自定义解析逻辑,将字符串转换为A类实例。

  • 自定义文本格式:如果需求简单,可以自己定义格式,比如每行采用参数列表:值的形式:

    a=1:2
    a=3,b=4:5
    b=6:7
    

    自己编写解析函数,分割每行的键值部分,将参数转换为A实例。

内容的提问来源于stack exchange,提问作者Daniil Lantukhov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 00:50:28