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)がオブジェクトのdictを埋めるために使用されるためです。

ここの誰かがそれについて知っていますか?

私はpython3で作業していますが、python2で簡単な評価を行い、同じことを観察しました。

編集

私がやりたかったこと:リンクされた例(ドキュメント)にとどまるために、Monstersが。nameで始まる場合はB、の値を2倍にします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 に答える