在 PyYAML 中使用自定义 class 键反序列化字典失败
Deserializing dictionary with custom class keys fail in PyYAML
我试图使用 PyYAML 序列化一个使用 SampleClass
实例作为键的字典。它序列化正常,但是当我试图用 yaml.load()
加载它时,它引发了一个异常:
AttributeError: 'SampleClass' object has no attribute '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)))
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_yaml
和 from_yaml
例程
至 SampleClass
并注册 class
(doc)。这个
允许您消除不安全的加载(顺便说一句
PyYAML 的默认值)。
我试图使用 PyYAML 序列化一个使用 SampleClass
实例作为键的字典。它序列化正常,但是当我试图用 yaml.load()
加载它时,它引发了一个异常:
AttributeError: 'SampleClass' object has no attribute '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)))
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_yaml
和 from_yaml
例程
至 SampleClass
并注册 class
(doc)。这个
允许您消除不安全的加载(顺便说一句
PyYAML 的默认值)。