デフォルトでは、PyYAML を使用してダンプ ( print(yaml.dump(MyObj()))
) すると、次のようになります。
!!python/object:__main__.MyObj {}
PyYAML は、目的の出力のコメントに対して 1 つのことしか実行できません: それらを破棄します。目的の出力を読み戻すと、dict を含む dict になります (タグ情報が{'boby': {'age': 34}}
ないため、インスタンスは取得されません)。MyObj()
私が開発した PyYAML の拡張バージョン ( ruamel.yaml ) は、YAML をコメント付きで読み取り、コメントを保持し、ダンプ時にコメントを書き込むことができます。目的の出力を読み取ると、結果のデータは dict を含む dict のように見えます (そして動作します) が、実際にはコメントを処理できるより複雑なデータ構造があります。ただし、ruamel.yaml が のインスタンスをダンプするように要求したときにその構造を作成できますMyObj
。そのときにコメントを追加すると、目的の出力が得られます。
from __future__ import print_function
import sys
import ruamel.yaml
from ruamel.yaml.comments import CommentedMap
class MyObj():
name = "boby"
age = 34
def convert_to_yaml_struct(self):
x = CommentedMap()
a = CommentedMap()
x[data.name] = a
x.yaml_add_eol_comment('this is the name', 'boby', 11)
a['age'] = data.age
a.yaml_add_eol_comment('in years', 'age', 11)
return x
@staticmethod
def yaml_representer(dumper, data, flow_style=False):
assert isinstance(dumper, ruamel.yaml.RoundTripDumper)
return dumper.represent_dict(data.convert_to_yaml_struct())
ruamel.yaml.RoundTripDumper.add_representer(MyObj, MyObj.yaml_representer)
ruamel.yaml.round_trip_dump(MyObj(), sys.stdout)
どちらが印刷されますか:
boby: # this is the name
age: 34 # in years
CommentedMap
インスタンスを表現するまで、インスタンスの作成を待つ必要はありませんMyObj
。たとえば、適切な から/に対して値を取得/設定するプロパティにname
とを作成します。そうすれば、インスタンスを表すために静的メソッドが呼び出される前に、コメントをより簡単に追加できます。age
CommentedMap
yaml_representer
MyObj