ruamel.yaml.representer.RepresenterError: cannot represent an object: {'value': }

ruamel.yaml.representer.RepresenterError: cannot represent an object: {'value': }

对于 Python 3.7,我收到以下错误:

 `ruamel.yaml.representer.RepresenterError: cannot represent an object: {'a': 3}`

以下代码取自 PyYAML - Saving data to .yaml files 的答案。我该如何解决这个错误?

from ruamel.yaml import YAML

class Config(dict):
    def __init__(self, filename, auto_dump=True):
        self.filename = filename
        self.auto_dump = auto_dump
        self.changed = False
        self.yaml = YAML()
        self.yaml.preserve_quotes = True
        # uncomment and adapt to your specific indentation
        # self.yaml.indent(mapping=4, sequence=4, offset=2)
        if os.path.isfile(filename):
            with open(filename) as f:
                # use super here to avoid unnecessary write
                super(Config, self).update(self.yaml.load(f) or {})

    def dump(self, force=False):
        if not self.changed and not force:
            return
        with open(self.filename, "w") as f:
            self.yaml.dump(self, f)
        self.changed = False

    # following methods unchanged from PyYAML example
    def updated(self):
        if self.auto_dump:
            self.dump(force=True)
        else:
            self.changed = True

    def __setitem__(self, key, value):
        super(Config, self).__setitem__(key, value)
        self.updated()

    def __delitem__(self, key):
        super(Config, self).__delitem__(key)
        self.updated()

    def update(self, kwargs):
        super(Config, self).update(kwargs)
        self.updated()


cfg = Config("test.yaml")
print(cfg)
cfg['a'] = 3  # <=Error occurs
print(cfg)
cfg.update({"b": 4})
cfg.update(c=5)
del cfg['a']
print(cfg)

相关:

“PyYAML - 将数据保存到.yaml文件”中的代码似乎没有经过测试, 通常会有一些输出(自动包含在答案中 我post).

代码几乎可以工作,但需要将 self 转换为 dict 才能获得 键值对,否则 ruamel.yaml 尝试转储属性(.filename,等等)。

如果你想要.update()的(dict-like)参数和键值参数 你需要扩展它的参数列表:

import os
from ruamel.yaml import YAML

class Config(dict):
    def __init__(self, filename, auto_dump=True):
        self.filename = filename
        self.auto_dump = auto_dump
        self.changed = False
        self.yaml = YAML()
        self.yaml.preserve_quotes = True
        # uncomment and adapt to your specific indentation
        # self.yaml.indent(mapping=4, sequence=4, offset=2)
        if os.path.isfile(filename):
            with open(filename) as f:
                # use super here to avoid unnecessary write
                super(Config, self).update(self.yaml.load(f) or {})

    def dump(self, force=False):
        if not self.changed and not force:
            return
        with open(self.filename, "w") as f:
            self.yaml.dump(dict(self), f)
        self.changed = False

    # following methods unchanged from PyYAML example
    def updated(self):
        if self.auto_dump:
            self.dump(force=True)
        else:
            self.changed = True

    def __setitem__(self, key, value):
        super(Config, self).__setitem__(key, value)
        self.updated()

    def __delitem__(self, key):
        super(Config, self).__delitem__(key)
        self.updated()

    def update(self, *args, **kw):
        for arg in args:
            super(Config, self).update(arg)
        super(Config, self).update(**kw)
        self.updated()


cfg = Config("test.yaml")
print(cfg)
cfg['a'] = 3  # <=Error occurs
print(cfg)
cfg.update({"b": 4})
cfg.update(c=5)
del cfg['a']
print(cfg)

print('------')
print(open(cfg.filename).read())

给出:

{}
{'a': 3}
{'b': 4, 'c': 5}
------
b: 4
c: 5

这会像字典一样转储配置并且没有标签 在 YAML 中指示已转储的内容,没有任何内容可以帮助识别 在回读配置期间。所以IMO会更好 以正常方式将其设为可转储 class 并使用 !Config.

之类的标签进行转储