YAMLのススメ

YAMLのススメ

Intro

広く使われてるJSONは、コメントが許可されていなかったり、複雑な構造を持つときに読みにくくなったりする。(すでにこれらに対応した拡張形式はあるものの)いつ頃デファクトスタンダードとして対応されるんだろうと思っていたけど、これはYAMLに乗り換える流れだと気付いてしまった。

Tweet

プロジェクト内で作成した簡単なPython実行ファイルの設定部分をhard codingの状態から外部設定ファイルから読み取る形式に書き換えた。その際、jsonでは入力の手間が大きそうだったのでYAMLを選択したというお話。

TL; DR

  • JSONとYAMLの違いを理解する。
  • YAMLを使って設定ファイルを書く際のメリットを知る。
  • YAMLの書き方を学ぶ。
  • PythonでYAMLを読み書きする方法を知る。

JSON

そもそもIntroに登場したJSONとは、という説明から入ろう。

JSONはJavaScript Object Notationの略で、データのやり取りに使われる軽量なデータ形式である。JSONは、プログラミング言語に依存しない形式でデータを表現するため、データのやり取りに適している

いわゆる辞書や連想配列とほとんど同じ形式だ。キーと値のペアを持ち、キーは文字列で、値は文字列、数値、真偽値、配列、辞書などのいずれかの型を持つことができる。

1
2
3
4
5
6
7
8
9
10
{
"name": "Alice",
"age": 30,
"is_student": false,
"hobbies": ["reading", "swimming", "cooking"],
"address": {
"city": "Tokyo",
"country": "Japan"
}
}

さらに、ほとんどすべての言語でJSONを扱うためのライブラリが提供されているため、外部とのデータのやり取りに非常に適している。たとえばWeb REST APIのレスポンスや設定ファイルの読み書きに使われることが多い。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import json

json_str = """
{
"name": "Alice",
"age": 30,
"is_student": false,
"hobbies": ["reading", "swimming", "cooking"],
"address": {
"city": "Tokyo",
"country": "Japan"
}
}
"""

json_dic = json.loads(json_str)
# 文字列に変換する場合
json.dumps(json_dic)
# ファイルに書き出す場合
json.dump(json_dic, open("data.json", "w"))
1
2
json_dic = JSON.parse(json_str);
json_dumped = JSON.stringify(json_dic);

この通り、JSONはデータのシリアライズや設定ファイルの記述に適している。しかし、JSONにはいくつかの制約がある。

  • コメントが許可されていない
  • 複雑な構造を持つときに読みにくくなる
  • 文字列を記述するために、"で囲む必要がある

人間が読み書きする際に、これらの制約が不便に感じることがある。そのため、YAMLが登場した。

YAML

Yamlは、YAML Ain’t Markup Languageの略で、人間にとって読みやすいデータ形式である。YAMLは、データのシリアライズや設定ファイルの記述に適している。人間にとって読みやすいデータ形式を目指しており、JSONよりも柔軟で直感的な記述が可能である。

たとえば先のjsonは、YAMLで以下のように表現できる。
必要に応じてコメントや空白行を挟むこともできる

1
2
3
4
5
6
7
8
9
10
11
12
13
name: Alice
# 年度初め時点の年齢
age: 30
is_student: false
# 最大で5個まで
hobbies:
- reading
- swimming
- cooking
# 辞書の中に辞書
address:
city: Tokyo
country: Japan

なお、YAMLファイルは拡張子.yamlまたは.ymlで保存される。

YAMLの書き方

YAMLは、JSONと同じく左側にkey、右側にvalueを記述する形式である。ただし、YAMLではインデントを使って階層構造を表現する。つまり、valueに辞書や配列を持つ場合、その要素はインデントされる。なお、インデントはスペース2つかスペース4つが一般的だ。

詳細はYAML 入門: サンプルから学べる初心者向けガイド - circle ciブログを参照。

YAMLの読み書き

JSONはすでにあまりに広く使われているため、ライブラリについては標準に含まれている、あるいは読み込む必要すらないこともあった。しかし、YAMLはそうではない。PythonではPyYAMLというライブラリを使う

installはpip install pyyamlで行う。
実際の読み書きは以下のように行う。

1
2
3
4
5
6
7
8
9
import yaml

# 読み取り
loaded_yaml = yaml.safe_load(open("data.yaml", "r"))

# 何らかの処理

# 書き込み
yaml.dump(loaded_yaml, open("data.yaml", "w"))

Info

本筋とは逸れるが、ファイルの読み書きを行う際は、常にエンコードに気を付けよう。UTF8系統はあくまでデファクトスタンダードであって、未だ必ず保証される存在ではないのだ。というかWindowsのOfficeやOSに近い領域はShiftJIS系がデファクトスタンダードだったりする。
PythonでShiftJIS系のファイルを読み取る場合は、以下のように行う。

1
lines = open("data.yaml", "r", encoding="sjis").read().splitlines()

まとめ

YAMLは、JSONよりも人間にとって読みやすいデータ形式である。JSONはデータのシリアライズや設定ファイルの記述に適しているが、コメントが許可されていない、複雑な構造を持つときに読みにくくなる、文字列を記述するために"で囲む必要があるなどの制約がある。そのため、YAMLはJSONよりも柔軟で直感的な記述が可能であり、人間が読み書きする際に便利である。

コメント