如何在使用yaml.dump时忽略属性?

问题描述 投票:2回答:1

我试图在对一个对象进行YAML dump时隐藏某些属性。 我试过 这个 答案,它允许你转储,但加载不起作用。

import yaml
from copy import deepcopy

class SecretYamlObject(yaml.YAMLObject):
    hidden_fields = []

    @classmethod
    def to_yaml(cls, dumper, data):
        new_data = deepcopy(data)
        for item in cls.hidden_fields:
            del new_data.__dict__[item]
        return dumper.represent_yaml_object(cls.yaml_tag, new_data, cls,
                                            flow_style=cls.yaml_flow_style)

class Trivial(SecretYamlObject):
    hidden_fields = ["_ignore"]
    yaml_tag = u'!!Trivial'
    def __init__(self):
        self.a = 1
        self.b = 2
        self._ignore = 3

运行这段代码

import yaml
yaml.load('!Trivial {a: 1, b: 2}')

我得到以下错误。

ConstructorError: could not determine a constructor for the tag '!Trivial'in "", line 1, column 1: !Trivial {a: 1, b: 2} 的构造函数。

我试着 "黑 "了它,使yaml能用一个 族类属性 使用类似这样的东西。

class SecretYamlObject(yaml.YAMLObject):
    # ... same as before... remove for brevity

class Trivial(SecretYamlObject):
    hidden_fields = ["_ignore"]

    @classproperty # decorator definition not shown here for brevity 
    def yaml_tag(cls):
        return ('!!')+'python/object:'+'{}.{}'.format(cls.__module__, cls.__name__)

    def __init__(self):
        self.a = 1
        self.b = 2
        self._ignore = 3

这会产生一个坏的yaml字符串

import yaml
from secret_yaml2 import Trivial
print yaml.dump(Trivial())

!%21pythonobject:secret_yaml2.Trivial {a: 1, b: 2}。

出于某种原因,它将第二个 !%21...这又会导致一个构造函数错误。

另外,下面的方法可行,但我需要在加载yaml之前知道对象的类,而我可能不知道。

import yaml
from secret_yaml import Trivial
yaml.load(yaml.dump(Trivial()))

我试图制作一个知道如何正确地将自己转储到yaml的类,但我仍然可以通过正常的yaml.load调用来加载它。

python serialization deserialization pyyaml
1个回答
1
投票

你可以定义 __getstate__ 它被Python原生pickle和PyYaml使用。

class A(object):
    def __init__(self):
        self.hidden = 42
        self.visible = 5

    def __getstate__(self):
        state = self.__dict__.copy()
        del state['hidden']
        return state

a = A()
d = yaml.dump(a)
print(d)

这个打印。

!!python/object:__main__.A
visible: 5

这是在PyYaml或Pickle等序列化器中忽略或隐藏属性的最好方法。

© www.soinside.com 2019 - 2024. All rights reserved.