我已尝试按照here的说明操作,这使我得到了以下代码:
import yaml
class Step(yaml.YAMLObject):
yaml_tag = "!step"
def __init__(self, *args, **kwargs):
raise Exception("Intentionally.")
yaml.load("""
--- !step
foo: bar
ham: 42
""")
预期行为:我得到一个例外。但我观察到的是,我的YAML标记导致Step
实例,我能够使用它,访问方法,属性(如上面代码中的foo
)等等。阅读文档,我找不到我的错误,因为它表明使用所有键值对作为关键字参数调用构造函数。
基本上,doc中的示例可以工作,但不是因为构造函数的实现,而是因为键值对(Monster
的属性)用于填充对象的dict。
这里有人都知道吗?
我正在使用python3,但在python2中进行了快速评估并观察到了相同的内容。
修改的
我想做的事情:要留在链接的示例(文档)中,如果Monster
name
以B
开头,则ac
的值加倍
答案 0 :(得分:4)
来自文档:
yaml.YAMLObject使用元类魔法来注册构造函数,该构造函数将YAML节点转换为类实例,以及将类实例序列化为YAML节点的表示器。
在内部,constructor
注册的默认yaml.YAMLObject
会调用YourClass.__new__
,然后使用instance.__dict__
设置课程中的字段。有关详细信息,请参阅this method。
根据您要执行的操作,您可以在Step.__new__
中添加一些逻辑(但您不会获得**kwargs
或register a custom constructor中的任何字段。< / p>
答案 1 :(得分:0)
我认为我有一个根本的误解。我不知道这个假设是否成立,但我认为
load, dump = yaml.load, yaml.dump
foo = "any valid yaml string"
load(foo) == load(dump(load(foo))) # should be true
如果我现在按照我在问题中建议的那样做,在加载时真正改变属性,会改变这个“等式”并导致我很可能不想要的行为。