スクリプトのお勉強

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はお手軽だけどあまり融通は利かない

最後に

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

-スクリプトのお勉強
-

執筆者:

関連記事

言語別ログイン機能パスワード保存処理方針

ちょっと前に、ログイン機能を作成した際、パスワードを暗号化するか、という議論を目にしたことがありました。 昔だと、「パスワードを暗号化しない」方で実装していましたが、最近はセキュリティが当たり前になっ …

小ネタ: JavaScriptにてBase64エンコード/デコードする方法

小ネタです。JavaScriptにてBase64エンコード/デコードをしようとして、意外と詰まったので、メモ的に方法を書いておきます。 結論: js-base64ライブラリを使用する これだけです。。 …

Python3 – django-webtest

忙しいので断片だけ。。 DjangoでWebブラウザからアクセスする感じでテストする、やり方の一つです。以前にやったように、 Seleniumからやってもいいのすが、そこまでじゃない場合の単体テスト方 …

Certbot(snap版)の起動が失敗した件

certbotの起動が失敗した 小ネタです。 なぜかSSL証明書が更新されず、Let’s Encrypt Expiry Botからたくさんメールが来るなーと思ったらcertbotの起動が失 …

yoyo-migrationsを使ってみる

勉強用に、PythonでPostgresqlを制御しようと思います。 その前に、Postgresqlの設定と、マイグレーションをしようかと思います。まずyoyo-migrationsを使用します。 y …

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