:ruamel.yaml
0.15.19のあなたYAMLObject
のサブクラス化せずに1文を使用してregister classes、次のことができます。
yaml = ruamel.yaml.YAML()
yaml.register_class(User)
YAMLObject
はPyYAMLととの後方互換性のためにそこにある、とそれは便利かもしれませんが、私は本当に三つの理由のためにそれを使用することをお勧めすることはできません。
- それはあなたのクラス階層を依存させます、あなたが気づいたように、他の依存関係
- それはデフォルト
- として便利であまり邪魔になり、Pythonのデコレータに基づくソリューションにより、危険な
Loader
使用を妨害する可能性がYAMLObject
、上。 YAMLObject
をサブクラス化することはありません
唯一の本物はそのyaml_tag
ためconstructor
およびサブクラスのrepresenter
を登録しています。
すべての例では、Python 2を実行するとfrom __future__ import print_function
と仮定しています。
あなたがサブクラス化YAMLObject
に基づいて、以下、持っている場合:
import sys
import ruamel.yaml
from ruamel.std.pathlib import Path
yaml = ruamel.yaml.YAML(typ='unsafe')
class User(ruamel.yaml.YAMLObject):
yaml_tag = u'user'
def __init__(self, name, age):
self.name = name
self.age = age
@classmethod
def to_yaml(cls, representer, node):
return representer.represent_scalar(cls.yaml_tag,
u'{.name}-{.age}'.format(node, node))
@classmethod
def from_yaml(cls, constructor, node):
# type: (Any, Any) -> Any
return User(*node.value.split('-'))
data = {'users': [User('Anthon', 18)]}
yaml.dump(data, sys.stdout)
print()
tmp_file = Path('tmp.yaml')
yaml.dump(data, tmp_file)
rd = yaml.load(tmp_file)
print(rd['users'][0].name, rd['users'][0].age)
あなたを取得します:
:
users: [!<user> Anthon-18]
Anthon 18
をあなたが行うことによって、サブクラス化せずに正確に同じ結果を得ることができます
import sys
import ruamel.yaml
from ruamel.std.pathlib import Path
yaml = ruamel.yaml.YAML(typ='safe')
class User(object):
yaml_tag = u'user'
def __init__(self, name, age):
self.name = name
self.age = age
@classmethod
def to_yaml(cls, representer, node):
return representer.represent_scalar(cls.yaml_tag,
u'{.name}-{.age}'.format(node, node))
@classmethod
def from_yaml(cls, constructor, node):
# type: (Any, Any) -> Any
return User(*node.value.split('-'))
yaml.representer.add_representer(User, User.to_yaml)
yaml.constructor.add_constructor(User.yaml_tag, User.from_yaml)
data = {'users': [User('Anthon', 18)]}
yaml.dump(data, sys.stdout)
print()
tmp_file = Path('tmp.yaml')
yaml.dump(data, tmp_file)
rd = yaml.load(tmp_file)
print(rd['users'][0].name, rd['users'][0].age)
上記では、SafeLoader
(およびSafeDumper
)、これは正しい方向の一歩です。しかし、上記のXXXX.add_YYY
行を追加することは、クラスがたくさんある場合は迷惑です。そのようなエントリはほぼ同じですが、全く同じではないためです。そして、to_yaml
とfrom_yaml
のいずれかまたは両方が欠けているクラスは処理されません。
import sys
from ruamel.std.pathlib import Path
from myyaml import yaml, yaml_object
@yaml_object
class User(object):
yaml_tag = u'user'
def __init__(self, name, age):
self.name = name
self.age = age
@classmethod
def to_yaml(cls, representer, node):
return representer.represent_scalar(cls.yaml_tag,
u'{.name}-{.age}'.format(node, node))
@classmethod
def from_yaml(cls, constructor, node):
# type: (Any, Any) -> Any
return User(*node.value.split('-'))
data = {'users': [User('Anthon', 18)]}
yaml.dump(data, sys.stdout)
print()
tmp_file = Path('tmp.yaml')
yaml.dump(data, tmp_file)
rd = yaml.load(tmp_file)
print(rd['users'][0].name, rd['users'][0].age)
を再び同じ結果と:あなたが行うことができます持つ
import ruamel.yaml
yaml = ruamel.yaml.YAML(typ='safe')
class SafeYAMLObject(object):
def __init__(self, cls):
self._cls = cls
def to_yaml(self, representer, data):
return representer.represent_yaml_object(
self._cls.yaml_tag, data, self._cls,
flow_style=representer.default_flow_style)
def from_yaml(self, constructor, node):
return constructor.construct_yaml_object(node, self._cls)
def yaml_object(cls):
yaml.representer.add_representer(
cls, getattr(cls, 'to_yaml', SafeYAMLObject(cls).to_yaml))
yaml.constructor.add_constructor(
cls.yaml_tag, getattr(cls, 'from_yaml', SafeYAMLObject(cls).from_yaml))
return cls
:私はあなたがファイルmyyaml.py
にデコレータyaml_object
とヘルパークラスを作る提案する上で解決するために
。あなたはto_yaml
とfrom_yaml
方法を削除する場合は、同じ最終値が、わずかに異なるYAMLはなります
users:
- !<user> {age: 18, name: Anthon}
Anthon 18
私はこれをテストすることができていないが、代わりにサブクラスYAMLObject
のこのデコレータを使用することを取り除く必要がありますTypeError
やって:
class SQLUser(Base, User):
は 免責事項を¹:私はこのANSで使用ruamel.yaml
パッケージの作者ですワー。
免責事項2:私は本当に18ではないが、私はブライアン・アダムスのadagiumに従ってくださいは
あなたは 'ダンプできるようにYAMLObject''を継承する必要はありませんthisアルバムのタイトル曲で表現しましたユーザー '。サブクラス化は、IMOがダンピングとロードを可能にする最も邪魔な方法です。また、 'User'クラスは' yaml_tag'を持たないのでおそらく動作しません。 'YAMLObject'への依存を取り除いていますか? – Anthon
@Anthon申し訳ありませんが、私は 'yaml_tag'を省略しましたが、そこにあります。私は私の質問を編集しました。 'User'クラスはそれ自身で正しく動作します(クラスをYAMLファイルに正しくダンプできるように' to_yaml'メソッドを実装しました)。私はすべてにオープンですが、このようにして、エンドユーザに透明な方法でオブジェクトをダンプすることができます。 'yaml.dump'だけが期待どおりに動作します... – SolidSnake
[ruamel.yaml'への登録と装飾](http://yaml.readthedocs.io/ja/latest/dumpcls.html)を追加しました。あなたが実際に使用した答えの中のどの解決策がわかりませんが、登録はあなたのために機能するはずです。飾り付けは、それがするラッピングのために依然として干渉する可能性があります。 – Anthon