如何在 yaml.dump 或 yaml.safe_dump 中使用 OrderedDict 作为输入?

yab*_*exu 5 python yaml

我的问题很简单。我有一个带有自定义订单的 OrderredDict 对象,我想将其转换为 yaml 格式。但似乎 yaml.dump 不能将 Orderredict 作为输入。有谁知道怎么做?

Eth*_*n T 7

看起来您想要这个解决方案,它为 YAML 添加了一个“代表”。

假设您有一个my_object由嵌套列表、字典和/或 OrderedDicts 组成的对象……如果添加以下行,您可以将其转储到 YAML:

yaml.add_representer(OrderedDict, lambda dumper, data: dumper.represent_mapping('tag:yaml.org,2002:map', data.items()))
output = yaml.dump(my_object)
Run Code Online (Sandbox Code Playgroud)

我还发现有必要将我的元组转换为列表:

yaml.add_representer(tuple, lambda dumper, data: dumper.represent_sequence('tag:yaml.org,2002:seq', data))
Run Code Online (Sandbox Code Playgroud)


Yon*_*son 1

也许这就是您所需要的?

import yaml 
from collections import OrderedDict

def dump_ordered_yaml(ordered_data, output_filename, Dumper=yaml.Dumper):
    class OrderedDumper(Dumper):
        pass

    class UnsortableList(list):
        def sort(self, *args, **kwargs):
            pass

    class UnsortableOrderedDict(OrderedDict):
        def items(self, *args, **kwargs):
            return UnsortableList(OrderedDict.items(self, *args, **kwargs))

    OrderedDumper.add_representer(UnsortableOrderedDict, yaml.representer.SafeRepresenter.represent_dict)
    with open(output_filename, "w") as f:
        yaml.dump(ordered_data, f, Dumper=OrderedDumper)
Run Code Online (Sandbox Code Playgroud)

用法:

a = OrderedDict([('x', 11), ('y', 22)])
dump_ordered_yaml(a, "/tmp/ordered.yaml")
Run Code Online (Sandbox Code Playgroud)

终端结果:

cat /tmp/ordered.yaml
!!python/object/apply:collections.OrderedDict
- - [x, 11]
  - [y, 22]
Run Code Online (Sandbox Code Playgroud)