🙌

dataclasses.dataclassの応用例、環境設定を受け取る

2023/04/03に公開

俗にフルスタックフレームワークと呼ばれるミドルウェアでは設定をハードコーディングする場合が多い。config.py とか config.php がそれである。

しかしあらゆる案件に限らず文字列定数はソースコードの内外に定義できた方が何かと便利である。

最近はオワコンとされてる12条項アプリケーションでも同様の主張がある。

https://12factor.net/ja/config

12条項アプリケーションでは、環境変数を使うことを主張してるが、それに加えて小生はINIファイルを推したい。

もともと手書きでの運用を意識しており、セクション/key/valueにより大項目小項目の機能もある。

といいつつ、多くのプログラミング言語でサポートされる iniファイルライブラリでは連想配列で出力される場合が多く、使い勝手はあまり良くない。

https://docs.python.org/ja/3/library/configparser.html

https://rubygems.org/gems/inifile/versions/1.0.0

しかし少なくともPythonの場合dataclassesでこれを改善できる。

dataclassではメンバ変数と同名のキーワード引数による初期化を受け付けており、これが可変長引数に連想配列から直接流し込むのにとても都合がよい。

ありがちな mysql の接続を定義する場合を例示する。

https://github.com/kamawanu/zenn.dev-kamawanu-codes/blob/main/ini2dataclass/setting.ini

https://github.com/kamawanu/zenn.dev-kamawanu-codes/blob/main/ini2dataclass/read.py

configparserは Dict[str,str] なので dataclass の変数もかならずstrで受け取る必要がある。
mysql のポート番号は int の方が都合が良いので、property なりでintも直接取れるようにしたほうが後で面倒がない。

エラーになるのは __init__の間だけなので、 post init で変数を後出しで加工することはできる。

かくして、設定はあくまでINIファイル等の外部に書きながら、ソースコードで項目名と変数名を一致させることができる。

もちろんこれは環境変数からの初期化でも同様である。

ただdataclassでは、引数の過不足はエラーになるので、そこだけ注意が必要である。

Discussion