在 PyYAML 中格式化自定义类输出 [英] Formatting custom class output in PyYAML

查看:32
本文介绍了在 PyYAML 中格式化自定义类输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究一个简单的例子,但文档仍然让我有点困惑.
这是示例代码:

I'm working on a simple example here, but the docs still leave me a bit confused.
Here is the Example code:

class A(yaml.YAMLObject):
    yaml_tag = u'!A'

    def __init__(self, val):
        self.val = val

if __name__ == '__main__':
    t = datetime.time()
    a = A(t)
    print yaml.dump(a)
    print yaml.load(yaml.dump(a)).val == t

输出是

!A val: !!python/object/apply:datetime.time ["\0\0\0\0\0\0"]

!A val: !!python/object/apply:datetime.time ["\0\0\0\0\0\0"]

正确

因此,它似乎忠实地进行了 d-/序列化,但是默认的时间对象格式仍有一些不足之处.我怎样才能让它更漂亮,同时保持我强大的卸载/加载能力?

So, it appears to be faithfully d-/serializing, but the default time object format leaves something to be desired. How can I make it prettier while preserving my mighty dump/load powers?

谢谢

推荐答案

重新定义文档中所有时间的时间格式

您可以使用 datetime.time 实例定义自己的序列化格式">PyYAML 的代表"和构造函数".

Redefine time format for all times in a document

You can define your own serialization format for any datetime.time instances in your documents using PyYAML 'representers' and 'constructors'.

import datetime

import yaml

time_format = '%H:%M:%S'


def time_representer(dumper, data):
    return dumper.represent_scalar(u'!time', data.strftime(time_format))


def time_constructor(loader, node):
    value = loader.construct_scalar(node)
    return datetime.datetime.strptime(value, time_format).time()


yaml.add_representer(datetime.time, time_representer)
yaml.add_constructor(u'!time', time_constructor)


class A(yaml.YAMLObject):
    yaml_tag = u'!A'

    def __init__(self, val):
        self.val = val


if __name__ == '__main__':
    t = datetime.time()
    a = A(t)
    print yaml.dump(a, default_flow_style=False)
    print yaml.load(yaml.dump(a)).val == t

将输出:

!A
val: !time '00:00:00'

True

只为特定班级重新定义时间格式

您还可以定义特定类如何序列化和反序列化.通过这种方式,您可以仅更改 A 的时间表示方式.YAMLObject 文档

import datetime

import yaml

time_format = '%H:%M:%S'

class A(yaml.YAMLObject):
    yaml_tag = u'!A'

    def __init__(self, val):
        self.val = val

    @classmethod
    def to_yaml(cls, dumper, data):
        dict_representation = {
            'val':data.val.strftime(time_format)
        }
        node = dumper.represent_mapping(u'!A', dict_representation)
        return node

    @classmethod
    def from_yaml(cls, loader, node):
        dict_representation = loader.construct_mapping(node)
        val = datetime.datetime.strptime(
            dict_representation['val'], time_format).time()
        return A(val)

if __name__ == '__main__':
    t = datetime.time()
    a = A(t)
    print yaml.dump([t,a], default_flow_style=False)

    loaded = yaml.load(yaml.dump([t,a]))
    print loaded[0] == t
    print loaded[1].val == t

将输出:

- !!python/object/apply:datetime.time
  - "\0\0\0\0\0\0"
- !A
  val: 00:00:00

True
True

这篇关于在 PyYAML 中格式化自定义类输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆