[英]dump an python object as yaml file
我在將下面顯示的 Python 對象轉儲到 yaml 文件時遇到問題。 我想知道是否有任何特定的對象類型/格式。
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
這個對象包含一個對象列表,我嘗試使用yaml.safe_dump
yaml.safe_dump(brandObject, file)
但我收到了這個錯誤:
yaml.representer.RepresenterError: cannot represent an object: Canon: /cameras/canon/
這個對象有問題嗎?
這是一篇舊帖子,但要補充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}
# @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 文檔。
如果你仍然想要safe_dump
怎么safe_dump
? 沒有dump
和麻煩為每個對象編寫一個代表,也沒有另一個依賴?
好吧,您可以編寫一個方法來捕獲所有內容,例如JSON SafeRepresenter
的“默認”參數,並覆蓋在 YAML SafeRepresenter
引發異常的SafeRepresenter
。
使用PyAML 3.12 的概念證明。
import yaml
yaml.SafeDumper.yaml_representers[None] = lambda self, data: \
yaml.representer.SafeRepresenter.represent_str(
self,
str(data),
)
例子:
>>> 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"
注意:有關namedtuple
特定主題,請參閱:通過PyYAML 序列化namedtuples
您需要為該類實現 __repr__ 。 您可以將 __str__ 用作 __repr__。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.