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


  AttributeError:“ SampleClass”对象没有属性“名称”


如何解决?
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)))

最佳答案

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的默认设置)。

关于python - 在PyYAML中使用自定义类 key 对字典进行反序列化失败,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55139124/

10-13 00:02