如何在不使用yaml.YAMLObject的情况下执行Python对象的yaml.safe_dump()和.safe_load()?

时间:2015-10-02 11:57:22

标签: python python-2.7 yaml pyyaml

我想用yaml.safe_dump()序列化一些对象。如何使用add_representer()add_constructor() ...

序列化Python对象

我无法将yaml.YAMLObject添加到Thing(第三方模块)而不想使用。

我做了这样的转储:

import yaml

class Thing(object):
  def __init__(self, name):
    self.name = name

def Thing_representer(dumper, data):
  return dumper.represent_mapping('!Thing', data.__dict__)

yaml.SafeDumper.add_representer(Thing, Thing_representer)
safe_dump = yaml.safe_dump(t)
print safe_dump

它运行正常,但我不知道如何构造函数?

def Thing_constructor(loader, data):
  thing = Thing()
  return thing.__dict__.update(loader.construct_mapping(data))

yaml.SafeLoader.add_constructor('!Thing', Thing_constructor)
yaml.safe_load(safe_dump)

抛出异常TypeError: __init__() takes exactly 2 arguments (1 given)并且应该抛出,因为构造函数需要参数。也许有另一个选项来构造对象跳过构造函数?

1 个答案:

答案 0 :(得分:1)

如果不提交名称,则无法构建Thing()。你可以解决这个问题 以各种方式,但以下应该有效。

def thing_constructor(self, node):
    name = None
    for x in node.value:
        if x[0].value == 'name':
            name = x[1].value
    return Thing(name)


yaml.SafeLoader.add_constructor('!Thing', thing_constructor)

res = yaml.safe_load(safe_dump)
print res.name

您可以简化name参数的设置,但是如果Thing采用了更多参数,这种方式更具可扩展性。