4

我尝试按照此处的说明进行操作,这使我得到了以下代码:

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上面的代码)等等。阅读文档,我找不到我的错误,因为它建议使用所有键值对作为关键字参数调用构造函数。

基本上文档中的示例有效,但不是因为构造函数的实现,而是因为键值对(的属性Monster)用于填充对象的字典。

这里有人知道吗?

我正在使用 python3,但在 python2 中进行了快速评估并观察到了相同的结果。

编辑

我想做的是:留在链接的示例(文档)中,如果Monstersname以 a 开头,则将 .B的值加倍ac

4

2 回答 2

5

从文档中:

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

constructor在内部,由注册的默认值yaml.YAMLObject将调用YourClass.__new__然后使用instance.__dict__. 有关更多详细信息,请参阅此方法

根据您想要做什么,您可以放入一些逻辑Step.__new__(但您不会获得任何字段**kwargs,或者注册自定义构造函数

于 2012-11-11T13:49:29.380 回答
0

我认为我有一个根本性的误解。我不知道这个假设是否成立,但我认为

load, dump = yaml.load, yaml.dump
foo = "any valid yaml string"

load(foo) == load(dump(load(foo))) # should be true

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

于 2012-11-11T18:22:05.023 回答