【问题标题】:How to do yaml.safe_dump() and .safe_load() of Python object without yaml.YAMLObject?如何在没有 yaml.YAMLObject 的情况下执行 Python 对象的 yaml.safe_dump() 和 .safe_load()?
【发布时间】:2015-12-30 15:14:15
【问题描述】:

我想用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) 并且应该抛出异常,因为构造函数需要参数。也许还有另一种选择来构造对象跳过构造函数?

【问题讨论】:

  • 您的第一个代码段中有一些虚假的换行符。当然t = Thing()(仍然)失踪了。

标签: python python-2.7 yaml pyyaml


【解决方案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需要更多的参数,这样扩展性会更好。

【讨论】:

  • 可以跳过__init__(),但我不知道怎么做。因此可以在不调用构造函数的情况下构造对象。也许我需要学习pyyaml里面的学习如何从映射中初始化对象。
  • 如果您无法控制真实的Thing(),我不确定是否有可能。您当然可以只给它一个虚拟名称,然后设置每个属性,但我并没有真正看到这种方法的用处,而且它会更慢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-22
  • 1970-01-01
  • 2022-08-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多