PythonでのJSONとYAML/TOMLの相互変換


PythonでのJSONとYAML/TOMLの相互変換

JSONだとコメントが書けない点が不便で、YAML/TOMLにチャレンジしてみました。configparserを利用するiniは今回の対象外です。

定義形式に慣れていない場合、最初からYAML/TOMLで定義を書き出すよりは、普段使いの定義ファイルから辞書経由で別形式に変換して進めるのが理解が早いと思います。プログラム内部では辞書経由でアクセスするため、処理自体を変える必要はないと思います。
今回は、以下のデータを元にテストしたいと思います。

dat.json[テストデータ]
{
  "country": "Japan",
  "user": [
    {
      "name": "Taro",
      "phone": ["111-222-3333", "222-333-4444"],
      "age": 10
    },
    {
      "name": "Hanako",
      "phone": ["555-666-777"],
      "age": 20
    }
  ]
}

変換方法

jsonに加えて、yamlおよびtomlライブラリを利用します。

JSON→YAML

JSONからYAMLに変換するにはyamlライブラリを利用します。

json2yaml.py
import yaml
import json

with open('dat.json') as file:
    # JSONから辞書
    obj = json.load(file)
    # 辞書からYAML
    ym = yaml.dump(obj, Dumper=yaml.CDumper)
    print(ym)
実行結果
country: Japan
user:
- age: 10
  name: Taro
  phone:
  - 111-222-3333
  - 222-333-4444
- age: 20
  name: Hanako
  phone:
  - 555-666-777

YAML→JSON

YAMLファイルのロードはsafe_loadを利用したほうがよさそうです。参照方法はJSONと同じなので違和感なく使えると思います。(処理結果は、当然変換前と同じになるので省略)

yaml2json.py
with open('dat.yaml') as file:
    # YAMLから辞書
    obj = yaml.safe_load(file)
    # 辞書からJSON
    js = json.dumps(obj, indent=2)
    print(js)

JSON→TOML

JSONからTOMLに変換するにはtomlライブラリを利用します。使い方はYAMLやJSONと同じです。なお、pytomlはメンテされていない模様。

json2toml.py
import toml
import json

with open('dat.json') as file:
    # JSONから辞書
    obj = json.load(file)
    # 辞書からTOML
    tm = toml.dumps(obj)
    print(tm)
実行結果
country = "Japan"
[[user]]
name = "Taro"
phone = [ "111-222-3333", "222-333-4444",]
age = 10

[[user]]
name = "Hanako"
phone = [ "555-666-777",]
age = 20

phone項目の最後のカンマがちょっと気になりますねw

TOML→JSON

TOMLの読み込みもJSON/YAMLと同じような使い方です。

toml2json.py
with open('dat.toml') as file:
    # TOMLから辞書
    obj = toml.load(file)
    # 辞書からJSON
    js = json.dumps(obj, indent=2)
    print(js)

まとめ

YAML/TOMLともに一長一短がありますが、JSONに慣れている人はTOMLのほうが読みやすいかなと感じました。

今後やりたいこと

toml.dumpsのTomlEncoderを独自実装して以下を対応したいと思います。
- TOMLでサブセクションのインデント対応(json.dumpsのindent相当)
- 配列の項目の最後のカンマを除去