许多不同对象的YAML安全加载

3

我有一个非常庞大的YAML文件,其中包含像此片段中的标记定义:

- !!python/object:manufacturer.Manufacturer
  name: aaaa
  address: !!python/object:address.BusinessAddress {street: bbbb, number: 123, city: cccc}

我需要先加载文件,以确保该文件是正确的YAML格式,并在给定上下文的情况下提取特定树深度的信息。这些信息都是嵌套的字典、列表和基本类型,很容易处理。但由于我没有原始的Python源码和类定义,所以无法使用yaml.load()进行加载。

我尝试了yaml.safe_load(),但是会抛出异常。BaseLoader可以加载文件,因此文件是正确的。但是它将所有基本信息(数字、日期时间)混合为字符串。

然后我发现了如何使用safe_load使用PyYAML反序列化对象,但由于文件中定义了100多个不同的标签,所以那里提供的解决方案并不实用。

我是否需要使用其他工具来去除!!tag定义(至少有一个场合,其中!!出现在普通字符串内),以便我可以使用safe_load。还有比我不知道的更简单的解决方法吗?

如果没有,我将不得不进行一些字符串解析以获取类型,但我想在这里先询问一下。

1个回答

2
如果您想在这样的文件上使用safe_loader(),则无需添加任何类。如果是这样,您应该会在constructor.py中的SafeConstructor.construct_undefined()中抛出一个ConstructorError。该方法在constructor.py文件中注册为“None”情况的回退案例。如果您将此信息与所有这些标记的“类”都是映射(而不是列表或标量)的事实相结合,那么您只需将映射代码复制到新函数中并将其注册为回退案例即可。
import yaml
from yaml.constructor import SafeConstructor

def my_construct_undefined(self, node):
    data = {}
    yield data
    value = self.construct_mapping(node)
    data.update(value)

SafeConstructor.add_constructor(
    None, my_construct_undefined)

yaml_str = """\
- !!python/object:manufacturer.Manufacturer
  name: aaaa
  address: !!python/object:address.BusinessAddress {street: bbbb, number: 123, city: cccc}
"""

data = yaml.safe_load(yaml_str)
print(data)

应该让你:

[{'name': 'aaaa', 'address': {'city': 'cccc', 'street': 'bbbb', 'number': 123}}]

没有抛出异常,并且将"number"作为整数而不是字符串。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接