使用yaml.dump时如何忽略属性?
How to ignore attributes when using yaml.dump?
我在对对象执行 YAML 转储时试图隐藏某些属性。我试过 this 答案,它允许你转储,但加载不起作用。
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}
我已经尝试 'hack' 它以便 yaml 可以使用 classproperty 使用类似这样的方法找到构造函数:
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())
!%21python/object:secret_yaml2.Trivial {a: 1, b:
2}
出于某种原因,它将第二个 !
转换为 %21
... 这再次导致构造函数错误。
顺便说一句,下面的工作,但我需要在加载 yaml 之前知道对象的 class,我可能不知道。
import yaml
from secret_yaml import Trivial
yaml.load(yaml.dump(Trivial()))
我正在尝试制作一个 class,它知道如何正确地将自己转储到 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 等序列化程序中忽略或隐藏属性的最佳方式。
我在对对象执行 YAML 转储时试图隐藏某些属性。我试过 this 答案,它允许你转储,但加载不起作用。
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}
我已经尝试 'hack' 它以便 yaml 可以使用 classproperty 使用类似这样的方法找到构造函数:
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())
!%21python/object:secret_yaml2.Trivial {a: 1, b: 2}
出于某种原因,它将第二个 !
转换为 %21
... 这再次导致构造函数错误。
顺便说一句,下面的工作,但我需要在加载 yaml 之前知道对象的 class,我可能不知道。
import yaml
from secret_yaml import Trivial
yaml.load(yaml.dump(Trivial()))
我正在尝试制作一个 class,它知道如何正确地将自己转储到 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 等序列化程序中忽略或隐藏属性的最佳方式。