🦾
YAMLWizard で順序を保ってシリアライズする
結論
encorder
として PyYAML の safe_dump(sort_keys=False)
を渡す。
import yaml as pyyaml
def encorder(data, **kw):
return pyyaml.safe_dump(data, sort_keys=False, **kw)
obj.to_yaml_file("obj.yml", encoder=encorder)
背景
Python で dataclass を yaml で serialize/deserialize したいなと思っていたら dataclass-wizard なるライブラリを見つけました。
from dataclasses import dataclass
from dataclass_wizard import YAMLWizard
@dataclass
class Kasega0(YAMLWizard):
name: str = "kasegao"
age: int = 23
k = Kasega0()
k.to_yaml_file("kasegao.yml")
こんな感じで手軽に yaml に dump できるのはありがたいのですが、このままだと次のように順序が保されずに出力されてしまいます。
age: 23
name: kasegao
これを元の定義順に保存してほしいなと思ったので方法を調べました。
方法
内部実装を読んでみるとデフォルトでは中で encoder
として PyYAML の dump()
を呼んでいるようでした。
YAMLWizard の内部実装
def to_yaml(self: T, *,
encoder: Optional[Encoder] = None,
**encoder_kwargs) -> AnyStr:
"""
Converts the dataclass instance to a YAML `string` representation.
"""
if encoder is None:
encoder = yaml.dump
return encoder(asdict(self), **encoder_kwargs)
よって encorder
として順序を保てる safe_dump(sort_keys=False)
を渡すことにしました。
import yaml as pyyaml
def encorder(data, **kw):
return pyyaml.safe_dump(data, sort_keys=False, **kw)
k.to_yaml_file("kasegao.yml", encoder=encorder)
これで無事順序を保って serialize できるようになりました。
name: kasegao
age: 23
Discussion