使用 pyyaml 序列化自定义 类

Serializing custom classes with pyyaml

我想通过指定应如何序列化此类 class 实例来序列化自定义 class(我无法修改或猴子补丁)。

设置如下:

# some custom class which I cannot modify
class Custom:
    def __init__(self, a, b):
        self.a = a
        self.b = b

# data I want to serialize
data = [Custom(1, 2), Custom(101, 102)]

下面是我为 JSON 做的:

import json

# helper function to handle the custom class
def default(d):
    if isinstance(d, Custom):
        return dict(a=d.a, b=d.b)

print(json.dumps(data, default=default))
# expected and actual output: [{"a": 1, "b": 2}, {"a": 101, "b": 102}]

我正在努力寻找 pyyaml 的等效解决方案:

import yaml

def yaml_equivalent_of_default():
    "YOUR SOLUTION GOES HERE"

print(yaml.dump(data))
# expected output:
# - a: 1
#   b: 2
# - a: 101
#   b: 102

我尝试了 pyyaml docs 中提到的不同方法,但都无济于事。

我相信如果可以 pickle 自定义 class members/fields,这应该可行:

import yaml

class Custom:
    def __init__(self, a, b):
        self.a = a
        self.b = b

data_to_serialize = [Custom(1, 2), Custom(101, 102)]

def yaml_equivalent_of_default(dumper, data):
    dict_representation = data.__dict__
    node = dumper.represent_dict(dict_representation)
    return node

yaml.add_representer(Custom, yaml_equivalent_of_default)

print(yaml.dump(data_to_serialize))

输出:

- a: 1
  b: 2
- a: 101
  b: 102

representer 的签名是 def add_representer(data_type, representer, Dumper=Dumper),因此可以将 Damper 传递给它。所有可用的转储程序都是 ['BaseDumper', 'SafeDumper', 'Dumper'].