YAML不会调用构造函数

时间:2012-11-11 12:43:39

标签: python python-3.x yaml

我已尝试按照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 nameB开头,则ac的值加倍

2 个答案:

答案 0 :(得分:4)

来自文档:

  

yaml.YAMLObject使用元类魔法来注册构造函数,该构造函数将YAML节点转换为类实例,以及将类实例序列化为YAML节点的表示器。

在内部,constructor注册的默认yaml.YAMLObject会调用YourClass.__new__,然后使用instance.__dict__设置课程中的字段。有关详细信息,请参阅this method

根据您要执行的操作,您可以在Step.__new__中添加一些逻辑(但您不会获得**kwargsregister 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

如果我现在按照我在问题中建议的那样做,在加载时真正改变属性,会改变这个“等式”并导致我很可能不想要的行为。