使用 PyYAML 加载自定义对象

Loading custom objects with PyYAML

我有一个如下所示的 YAML 文件:

!!com.example.hero.YAMLAnimals
animals:
  Land: [Cow, Lion]
  Sea: [Salmon, Cod]

根据 PyYAML 文档,我应该能够通过子类化 yaml.YAMLOBJECT 安全地加载 YAMLAnimals 对象。我试过这样做:

class YAMLAnimals(yaml.YAMLObject):
    yaml_tag = u'!com.example.hero.YAMLAnimals'

    def __init__(self, animals):
        self.animals = animals

但是,当我尝试使用 yaml.load()yaml.safe_load() 解析文件时,我收到以下错误:

could not determine a constructor for the tag 'tag:yaml.org,2002:com.example.hero.YAMLAnimals'

谢谢!

根据https://yaml.org/refcard.html!!<name>被认为是二级标签(按照惯例,意味着tag:yaml.org,2002:<name>)。因此,您应该将 YAMLAnimals 中的 yaml_tagu'!com.example.hero.YAMLAnimals' 更改为 u'tag:yaml.org,2002:com.example.hero.YAMLAnimals',以便解析 YAML 文件中的 !!com.example.hero.YAMLAnimals 标签。

另外正如@mgrollins 所指出的,您应该将 yaml.load 函数调用的 Loader 指定为 yaml.Loader 作为当前问题的临时解决方法(https://github.com/yaml/pyyaml/issues/266)[https://github.com/yaml/pyyaml/issues/266)

test.yaml

!!com.example.hero.YAMLAnimals
animals:
  Land: [Cow, Lion]
  Sea: [Salmon, Cod]

Python代码:

import yaml

class YAMLAnimals(yaml.YAMLObject):
    yaml_tag = u'tag:yaml.org,2002:com.example.hero.YAMLAnimals'
    def __init__(self, animals):
        self.animals = animals

stream = open('test.yaml', 'r')
data = yaml.load(stream, Loader=yaml.Loader)
stream.close()
print(data.animals)