如何为PyYAML编写代表?

who*_*nli 7 python yaml pyyaml

我希望有一个自定义函数来序列化任意python对象,比如json.dump函数如何有一个名为'default'的可选arg,它应该是json转储器在对象不是json可序列化时将调用的函数.

我只是想从json包中做相同的操作.

json.dump(tests_dump, file('somefile', 'w+'), default = lambda x: x.__dict__)
Run Code Online (Sandbox Code Playgroud)

看起来我需要从PyYAML文档中编写yaml.add_representer,但它真的不清楚如何做到这一点.

小智 5

以下是add_representer的示例.不确定这是不是你想要的.不过......

import yaml

#Arbitrary Class
class MyClass:
  def __init__(self, someNumber, someString):
    self.var1 = someNumber
    self.var2 = someString

#define the representer, responsible for serialization
def MyClass_representer(dumper, data):
    serializedData = str(data.var1) + "|" + data.var2
    return dumper.represent_scalar('!MyClass', serializedData )

#'register' it     
yaml.add_representer(MyClass, MyClass_representer)

obj = MyClass(100,'test')

print ( 'original Object\nvar1:{0}, var2:{1}\n'.format(obj.var1, obj.var2) )

#serialize
yamlData = yaml.dump(obj)

print('serialized as:\n{0}'.format(yamlData) )

#Now to deserialize you need a constructor
def MyClass_constructor(loader,node):
    value = loader.construct_scalar(node)
    someNumber,sep,someString = value.partition("|")
    return MyClass(someNumber,someString)

#'register' it    
yaml.add_constructor('!MyClass', MyClass_constructor)

#deserialize
obj2 = yaml.load(yamlData)

print ( 'after deserialization\nvar1:{0}, var2:{1}\n'.format(obj2.var1, obj2.var2) )
Run Code Online (Sandbox Code Playgroud)

当然有代码重复,代码没有优化.你可以让你的类的这两个功能部分,也是落实__repr__以获得可打印表示,你可以用它来填充serializedDataMyClass_representer

  • 那么如何“取消注册”添加的表示者和构造函数?我工作的环境中有其他工具依赖于不同的行为,我发现如果我像这样添加表示者和构造函数,它将改变 yaml 模块的行为,即使调用 yaml 的代码位于另一个文件中模块。 (2认同)