pythonでyamlを使ってみる
自作ソフトで今まで設定ファイルにConfigParserを使っていたのですが、
ふと思い立ってPyYamlを使ってみました。
yamlのよいところ
yaml.load一発で読み込める
(ConfigParserは項目毎に型を指定する必要がある)
yaml.dump一発で書き込める
(ConfigParserは項目毎に型を指定する必要がある)
独自の型を追加できる。
(ConfigParserでも出来るが、PyYamlは独自型の追加方法が系統だっている)
1. yaml.load一発で読み込める
もちろん、堅牢性を考えると、読み込んだデータの型が正しいかチェックが必要ですが、
そんなに複雑なコードは要りません。
from __future__ import with_statement, division, print_function import yaml #型チェック関数 #その型に変換できたら、変換した値を #変換できなかったらTypeError def ensure_int(x): try: return int(x) except (ValueError, TypeError): raise TypeError def ensure_str(x): if isinstance(x, basestring): return unicode(x) else: raise TypeError def ensure_strlist(x): if isinstance(x, list): x1 = list(x) return [ensure_str(i) for i in x1] else: raise TypeError types = dict( number=ensure_int, dirname=ensure_str, extpattern = ensure_strlist, ) ss = """ number : "xyz" dirname : "D:/Owner/My Documents/My Picture" extpattern : ["*.png", "*.jpg"] """ d = yaml.load(ss) for name, func in types.iteritems(): try: func(d[name]) except TypeError: print(name, "の型が違う")
また、簡単なプログラムなら、異常終了するに任せてもよいでしょう。
2. yaml.dump一発で書き込める
書き込む時は型チェックは普通要らないので、(型が違っていたら、それはバグ)
一々型を指定するのは冗長です。
3.独自の型を追加できる
当然ながら、対応したプログラムでしか読み込めなくなりますが。
#encoding:utf-8 from __future__ import with_statement, division, print_function import wx import yaml Dumper = yaml.SafeDumper Loader = yaml.SafeLoader ## wxColourインスタンスをノードに変換する関数 def color_representer(dumper, color): L = [color.Red(), color.Green(), color.Blue()] node = dumper.represent_sequence(u'!wxColour', L) return node Dumper.add_representer(wx.Colour, color_representer) ## ノードからColorインスタンスを復元する関数 def color_constructor(loader, node): L = loader.construct_sequence(node) return wx.Colour(L[0], L[1], L[2]) Loader.add_constructor(u'!wxColour', color_constructor) s = "!wxColour [255, 128, 64]" color = yaml.load(s, Loader=Loader) print(color) s1 = yaml.dump(s, Dumper=Dumper) print(s1)