【问题标题】:Deserializing dictionary with custom class keys fail in PyYAML在 PyYAML 中使用自定义类键反序列化字典失败
【发布时间】:2019-03-13 10:04:40
【问题描述】:

我试图使用 PyYAML 来序列化使用 SampleClass 实例作为键的字典。它可以序列化,但是当我尝试使用yaml.load() 加载它时,它会引发异常:

AttributeError: 'SampleClass' 对象没有属性 'name'

如何解决这个问题? SampleClass 看起来像这样:

import uuid

class SampleClass:

    def __init__(self, name = "<NO NAME>"):
        self.objects = []
        self.name = name
        self.id = uuid.uuid1()

    def __eq__(self, other):
        if isinstance(other, SampleClass):
            return self.name == other.name and \
                self.objects == other.objects and \
                self.id == other.id
        else:
            return False

    def __hash__(self):
        return hash((str(self.name), str(self.id)))

【问题讨论】:

    标签: python pyyaml


    【解决方案1】:

    PyYAML 有点过时了,它只支持已被 YAML 1.2 取代的 YAML 1.1 早在 2009 年。还请注意,虽然 PyYAML 可以解析 YAML 映射中的复杂键(例如,序列或映射本身的键),在 YAML 中有效的键,但它无法在 Python 中有效地构造它们无法加载这些。

    使用ruamel.yaml(免责声明:我是该软件包的作者),您可以这样做:

    import sys
    import uuid
    import ruamel.yaml
    from ruamel.yaml.compat import StringIO
    
    class SampleClass:
    
        def __init__(self, name = "<NO NAME>"):
            self.objects = []
            self.name = name
            self.id = uuid.uuid1()
    
        def __eq__(self, other):
            if isinstance(other, SampleClass):
                return self.name == other.name and \
                    self.objects == other.objects and \
                    self.id == other.id
            else:
                return False
    
        def __hash__(self):
            return hash((str(self.name), str(self.id)))
    
        def __repr__(self):
            return "SampleClass({})".format(self. name)
    
    data = {SampleClass("abc"): 1, SampleClass("xyz"): 42}
    
    yaml = ruamel.yaml.YAML(typ="unsafe")
    buf = StringIO()
    yaml.dump(data, buf)
    x = yaml.load(buf.getvalue())
    print(x)
    

    给出:

    {SampleClass(abc): 1, SampleClass(xyz): 42}
    

    我建议提供to_yamlfrom_yaml 例程 到SampleClass 并注册课程 (doc)。这个 允许您消除不安全的加载(顺便说一句 PyYAML 的默认值)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-09-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-24
      • 2012-03-31
      • 1970-01-01
      相关资源
      最近更新 更多