这是一篇旧帖子,但要补充Jayanth Koushik's answer:
不确定没有实现__repr__ 是这里的罪魁祸首。我尝试实现它,它仍然会引发错误,所以解决方案可能不正确:
import yaml
class CameraBrand():
def __init__(self, name, url):
self.rank = ""
self.name = name
self.url = url
self.models = []
def __str__(self):
return repr(self)
def __repr__(self):
return self.name + ": " + self.url
brand_object = CameraBrand('foo', 'http://foo.com')
print(yaml.safe_dump(brand_object))
还是加注yaml.representer.RepresenterError: cannot represent an object: foo: http://foo.com
其实答案可以在PyYaml documentation找到:“safe_dump只产生标准的YAML标签,不能代表任意的Python对象。”。因此,您只需要使用dump 而不是safe_dump:
>>> print(yaml.dump(brand_object))
!!python/object:__main__.CameraBrand
models: []
name: foo
rank: ''
url: http://foo.com
然而,一旦你这样做了,你会看到加载你的对象回来
- 不安全不推荐
yaml.load,
- 但是使用强烈推荐的
safe_load 会变得有点棘手。为此,您必须深入研究YAMLObject 和其他 PyYaml 类,这有点棘手。
或者,您可以使用 yamlable 库,它会为您自动执行其中一些 PyYaml 技巧。我写它是为了解决我们生产代码中的类似情况,以便更容易控制对象到 yaml 的绑定过程。在您的情况下,以下方法可以解决问题:
import yaml
from yamlable import YamlAble, yaml_info
@yaml_info(yaml_tag_ns='myyaml')
class CameraBrand(YamlAble):
def __init__(self, name, url):
self.rank = ""
self.name = name
self.url = url
self.models = []
def __str__(self):
return self.name + ": " + self.url
def to_yaml_dict(self):
return {'name': self.name, 'url': self.url}
# @classmethod
# def from_yaml_dict(cls, dct, yaml_tag):
# return CameraBrand(**dct)
brand_object = CameraBrand('foo', 'http://foo.com')
print(yaml.safe_dump(brand_object))
产量
!yamlable/myyaml.CameraBrand {name: foo, url: 'http://foo.com'}
和
print(yaml.safe_load("""!yamlable/myyaml.CameraBrand
name: foo
url: http://bar.com
"""))
正确加载对象并显示其字符串表示:
foo: http://bar.com
请注意,如果您希望在加载对象时执行一些自定义操作,也可以取消注释 from_yaml_dict 方法。详情请见yamlable documentation。