这是一篇旧帖,但为了补充Jayanth Koushik的答案:
我不确定没有实现__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文档中找到:“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}
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文档。
dict[in][out] = value
- alper