[英]dump an python object as yaml file
I am having problems dumping the Python object shown below to a yaml file.我在将下面显示的 Python 对象转储到 yaml 文件时遇到问题。 I was wondering whether there is any specific object type/format.
我想知道是否有任何特定的对象类型/格式。
class CameraBrand():
def __init__(self, name, url):
self.rank = ""
self.name = name
self.url = url
self.models = []
def __str__(self):
return self.name + ": " + self.url
This object contains a list of objects, and I tried to use yaml.safe_dump
这个对象包含一个对象列表,我尝试使用
yaml.safe_dump
yaml.safe_dump(brandObject, file)
But I got this error:但我收到了这个错误:
yaml.representer.RepresenterError: cannot represent an object: Canon: /cameras/canon/
Is there a problem with this object?这个对象有问题吗?
This is an old post but to complement Jayanth Koushik's answer :这是一篇旧帖子,但要补充Jayanth Koushik 的回答:
Not sure that having __repr__
not implemented is the culprit here.不确定没有实现
__repr__
是这里的罪魁祸首。 I tried implementing it and it still raises an error, so the solution is probably not correct:我尝试实现它,但它仍然引发错误,因此解决方案可能不正确:
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))
still raises yaml.representer.RepresenterError: cannot represent an object: foo: http://foo.com
仍然引发
yaml.representer.RepresenterError: cannot represent an object: foo: http://foo.com
Actually the answer can be found in PyYaml documentation : " safe_dump
produces only standard YAML tags and cannot represent an arbitrary Python object.".实际上答案可以在PyYaml 文档中找到:“
safe_dump
只生成标准的 YAML 标签,不能代表任意的 Python 对象。”。 Therefore you simply need to use dump
instead of safe_dump
:因此,您只需要使用
dump
而不是safe_dump
:
>>> print(yaml.dump(brand_object))
!!python/object:__main__.CameraBrand
models: []
name: foo
rank: ''
url: http://foo.com
However, once you do that, you will see that loading your object back但是,一旦你这样做,你会看到加载你的对象
yaml.load
,yaml.load
,safe_load
.safe_load
变得有点棘手。 For this you would have to dig a little bit into YAMLObject
and other PyYaml classes, and that is a bit tricky.YAMLObject
和其他 PyYaml 类,这有点棘手。 Alternatively, you can use the yamlable library, which automates a few of these PyYaml tricks for you.或者,您可以使用yamlable库,它会为您自动执行一些 PyYaml 技巧。 I wrote it to solve similar cases in our production code, in order to make it easier to control the object-to-yaml binding process.
我写它是为了解决我们生产代码中的类似情况,以便更容易控制对象到 yaml 的绑定过程。 In your case, the following would do the trick:
在您的情况下,以下方法可以解决问题:
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))
yields产量
!yamlable/myyaml.CameraBrand {name: foo, url: 'http://foo.com'}
and和
print(yaml.safe_load("""!yamlable/myyaml.CameraBrand
name: foo
url: http://bar.com
"""))
loads the object correctly back and displays its string representation:正确加载对象并显示其字符串表示形式:
foo: http://bar.com
Note that you can also uncomment the from_yaml_dict
method if you wish to perform some custom action when loading the object.请注意,如果您希望在加载对象时执行某些自定义操作,也可以取消注释
from_yaml_dict
方法。 See yamlable documentation for details.有关详细信息,请参阅yamlable 文档。
What if you still want to safe_dump
?如果你仍然想要
safe_dump
怎么safe_dump
? No dump
and bothering to write a representer for every object, nor another dependency?没有
dump
和麻烦为每个对象编写一个代表,也没有另一个依赖?
Well, you could write a method which will catch-all, like the "default" argument to the JSON dumpers and overwrite the one raising an exception in the YAML SafeRepresenter
.好吧,您可以编写一个方法来捕获所有内容,例如JSON
SafeRepresenter
的“默认”参数,并覆盖在 YAML SafeRepresenter
引发异常的SafeRepresenter
。
Proof of concept using PyAML 3.12.使用PyAML 3.12 的概念证明。
import yaml
yaml.SafeDumper.yaml_representers[None] = lambda self, data: \
yaml.representer.SafeRepresenter.represent_str(
self,
str(data),
)
Example:例子:
>>> import collections
>>> yaml.safe_dump([collections.namedtuple('Foo', 'bar')(1)])
'[Foo(bar=1)]\n'
>>> yaml.safe_dump(CameraBrand('Canon', '/cameras/canon/'))
"'Canon: /cameras/canon/'\n"
Note: for the namedtuple
specific topic, see : Serializing namedtuples via PyYAML注意:有关
namedtuple
特定主题,请参阅:通过PyYAML 序列化namedtuples
You need to implement __repr__ for the class.您需要为该类实现 __repr__ 。 You could just use your __str__ as __repr__.
您可以将 __str__ 用作 __repr__。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.