【问题标题】:How can I suppress 'None' output from yaml.dump, in Python?如何在 Python 中抑制 yaml.dump 的“无”输出?
【发布时间】:2015-11-21 03:12:50
【问题描述】:

我有一个(简化的)类,可以将其结构打印出来,无需进一步重新加载对象(yaml.load 将不会被使用)。

有没有一种快速的方法来抑制None 输出(包括设置为None 的变量)?也许yaml.representer 可以以某种方式使用。

import yaml

class A:
    def __init__(self):
        self.a = None
        self.b = [1,2,3]

    def __repr__(self):
        return yaml.dump(self)

A()

输出

!!python/object:__main__.A
a: null
b: [1, 2, 3]

而我需要:

!!python/object:__main__.A
b: [1, 2, 3]

此帖子仍然有效。我寻求简洁/稳健的想法。

【问题讨论】:

    标签: python class python-3.x data-structures yaml


    【解决方案1】:

    您可以通过继承YAMLObject 并定义to_yaml 类方法来做到这一点。对于您的特定示例:

    import yaml
    
    class A(yaml.YAMLObject):
        yaml_tag = u'!A'
    
        def __init__(self):
            self.a = None
            self.b = [1, 2, 3]
    
        def __repr__(self):
            return yaml.dump(self)
    
        @classmethod
        def to_yaml(cls, dumper, data):
            cleaned_data = dict((k, v) for (k, v) in data.__dict__.items() if v is not None)
            return dumper.represent_mapping(cls.yaml_tag, cleaned_data)
    

    上面的类方法跳过任何None 的值,只给我们我们想要的实例值。然后当我们使用它时,我们得到了我们期望的输出:

    >> print yaml.dump(A())
    !A
    b: [1, 2, 3]
    

    关于子类化YAMLObject:http://pyyaml.org/wiki/PyYAMLDocumentation#YAMLObject的文档

    yaml Dumper 上的文档: http://pyyaml.org/wiki/PyYAMLDocumentation#Dumper

    【讨论】:

    • 如果我的对象继承类yaml.YAMLObject,它们的内存占用会大大增加吗?任何粗略的性能/内存缺陷衡量标准?仅供参考:我可能有数百个子类实例......
    • 我不确定子类化类的内存占用。对不起。
    【解决方案2】:

    以下将是一种粗略的技术,将转储的输出转换为字符串然后格式化,但您可以在方法中很好地抽象它:

    >>> A()
    !!python/object:__main__.A
    a: null
    b: [1, 2, 3]
    
    >>> test = A()
    test_string = str(test)
    test_split = test_string.split("\n")
    
    >>> test_split
    ['!!python/object:__main__.A', 'a: null', 'b: [1, 2, 3]', '']
    
    >>> print test_split[0] + "\n" + test_split[2] + "\n"
    !!python/object:__main__.A
    b: [1, 2, 3]
    

    你可以把它塞进你的 repr 函数中。另一个标准库解决方案,我认为是最后一个,祝你好运:

    import yaml
    
    class A:
        def __init__(self):
            self.a = None
            self.b = [1,2,3]
            self.c = None
            self.d = 'wheee'
    
        def __repr__(self):
            string = re.sub(r'.*: null', '',str(yaml.dump(self)))
            string_split = string.split('\n')
            lines = [line for line in string_split if line.strip() != '']
            return '\n'.join(map(str, lines))
    

    在这种情况下,我们仍然得到预期的结果:

    !!python/object:__main__.A
    b: [1, 2, 3]
    d: wheee
    

    【讨论】:

    • 谢谢。有没有快速自动化的方法?
    • 我提到要抽象它,我已经用一种可能的解决方案更新了代码。
    • 谢谢。我确实想出了抽象 :) 我只是不确定如何设计它,以便它对 yaml.dump 任何复杂的输出都干净且不凌乱。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-08
    • 1970-01-01
    • 2013-12-15
    • 1970-01-01
    • 2012-10-30
    • 2013-06-04
    相关资源
    最近更新 更多