我试图在对一个对象进行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调用来加载它。
你可以定义 __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等序列化器中忽略或隐藏属性的最好方法。