【问题标题】:yaml safe_load of many different objects许多不同对象的 yaml safe_load
【发布时间】:2016-06-05 07:48:06
【问题描述】:

我有一个巨大的 YAML 文件,其中包含像这个 sn-p 中这样的标签定义

- !!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 加载文件,所以是正确的。但这会将所有原始信息(数字、日期时间)作为字符串混杂在一起。

然后我找到了How to deserialize an object with PyYAML using safe_load?,因为该文件定义了超过 100 个不同的标签,所以那里提出的解决方案是不切实际的。

我是否必须使用其他一些工具来去除 !!tag 定义(至少有一次!! 出现在普通字符串中),所以我可以使用 safe_load。有没有我不知道的更简单的方法来解决这个问题?

如果不是,我将不得不做一些字符串解析来恢复类型,但我想我先在这里问。

【问题讨论】:

    标签: deserialization yaml pyyaml


    【解决方案1】:

    如果您想在此类文件上使用safe_loader(),则无需执行添加任何类的繁琐路线。

    您应该在constructor.py 中获得ConstructorError 中的SafeConstructor.construct_undefined()。该方法在constructor.py 文件中注册为“无”案例。

    如果您将该信息与所有此类标记的“类”都是映射(而不是列表或标量)这一事实结合起来,您只需将映射代码复制到一个新函数中并将其注册为失败案例.

    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}}]
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多