スクリプトのお勉強

JSON/YAMLファイル読み込み用ライブラリ比較(Python3)

投稿日:

はじめに

Python3でプログラムを作る際、YAML/JSONを読みだす処理を多く作成します。
そうすると、データが長く、そして複雑になる時があります。

ネストしてるデータを読みだすと以下のように

a["bbbb"]["cddddd"]["alist"][0]["qqqq"]["ddddd"]

のようにやたら長くなって、かつなんだかよく分からなくなります。

ネストしてないときはa["bbbb"]の書き方がいい場合がありますが、長くなるとどうしても操作すべきデータが分からなくなってバグを生みやすくなります。

目標

以下の条件を満たす方法を探したいと考えています。

  • dot記法でアクセス可能 (MUST)
    • 例: a.b.c.d のようにアクセスできる。
  • 存在しないキーにアクセスした場合に例外ではなく None を返す (MUST)
    • 例: a.b.c.e と書いた場合、b が存在しない場合でも例外ではなく None を返してほしい。
  • 高速であること (SHOULD)
  • 辞書のキー順を保持する (SHOULD)
    • 例: YAMLファイルで {b: c: d: a:} のようなデータがあった場合、キーのリストを取得すると b, c, d, a の順で取得できる。
  • ソート可能であること (SHOULD)
    • 複雑な条件でもソートできる。
  • ソート前後で同一比較を行うと異なると判定される (SHOULD)
    • 必ずしも異なる必要はないが、チェックはしてみる。

ライブラリ候補

上記条件に適合しそうなライブラリとして、以下を検討しました。

  1. 自作 + SimpleNamespace + YAML
    • 使用ライブラリ: pyyaml (バージョン 6.0.2)
  2. python-box + YAML
    • 使用ライブラリ: python-box (バージョン 7.2.3)

なお、omegaconf という優れたライブラリもありますが、今回は実装がうまくいかなかったため割愛しました。
ファイル読み込みの場合、データが欠損することは少ないと考えられるため、今回は対象外としています。

環境

以下の環境で検証を行いました。

  • WSL2: ubuntu 24.04
  • Python3 3.12.3

ライブラリ候補の実装サンプル

サンプルコードはこちらに公開しています。

サンプルの動作内容は以下の通りです。

  • 固定のYAMLファイルを使用
    • 少し複雑なデータを用意。
  • 100回ループして処理を実行
    • timeit を使用して計測。

結果

以下の手順で準備を行います。

$ pip install -r requirement.txt

その後、以下のコマンドで実行します。

$ python3 ./time_test.py

box=42.12457203300437

simplenamespace=37.234188797010574

$ python3 ./time_test.py

box=42.320139449002454

simplenamespace=37.707468187989434

$ python3 ./time_test.py

box=42.18613590998575

simplenamespace=37.37725285399938

結論

  • (1) SimpleNamespace + YAMLの方が早い
  • (2) Boxはお手軽だけどあまり融通は利かない

最後に

自作部分のコードがやたらと長くなってしまいましたが、条件を満たす方法を見つけることができました。

-スクリプトのお勉強
-

執筆者:

関連記事

Svelte(Carbon Components Svelte) + Python(FastAPI)でWebアプリを作る

Svelte用のサンプルとして、Carbon Components SvelteのTreeViewを試用してファイルツリーを表示し、各データはAPIとして読み出し、編集するWebアプリケーションを実装 …

gradleのcommandLineでリダイレクト

gradleというビルドツールがあります。なぜかRPMを作成するのに使ってます。Ansibleも使ってるんですがね。。 それはともかく、ここの通りなのですが、例えばls -lRの出力を、プロジェクトデ …

poetry installでJSONDecodeError

小ネタです。OSをアップデートしたので、その他もいろいろアップデートしようとしたらエラーになったので、メモとして書いておきます。 WSL2のUbuntuを 22.04 LTSにアップデート は、さほど …

小ネタ: Python のdataclass でNone or “”を使わないJSONデータを定義する

PythonをREST APIのクライアントとして作成する際、dataclassesを使用しようと思いました。型が見た瞬間分かるし、しっかりしているからです。 でも、そのREST API は&#822 …

SPAMチェック for OCN の アップデート(v0.7.0)

以前、ここで書いたように、SPAMチェックのThunderbirdプラグインを作りました。 そして、Thunderbirdがアップデートしたので、Pluginもアップデートする必要があります。 正直放 …

google オプトアウト Click here to opt-out.