👋

pythonにはconstないけどclassとデコレータでそれっぽいのを作れるので別に困らない

2023/12/18に公開

python3には定数定義がない。
enumでもそれっぽいことはできなくもないが、コンセプトが違うのでいまいち使いにくい。

https://realpython.com/python-enum/

似たようなことを考えてるひとはもちろんたくさん居るのだが。

https://pypi.org/project/kkconst/

https://medium.com/@zeid.zandi/how-to-manage-constants-in-python-best-practices-and-advanced-techniques-50fa1591d517

https://qiita.com/nadu_festival/items/c507542c11fc0ff32529

仕方ないので作ることにした。

まずは使用例をご覧いただきたい。

https://github.com/kamawanu/zenn.dev-kamawanu-codes/blob/main/python3s/constant.py#L12-L21

まあまあの使い勝手だと自負してる。

サンプルを実行してもらえればわかるが、表面上は代入できても、中身は書き変わることはない。
見事にconstもどきの完成である。
(エラーを出すのが一般的だと思われるが、そこまでする意味はないと思ってる)

もちろん肝は makeitconst デコレータである。

https://github.com/kamawanu/zenn.dev-kamawanu-codes/blob/main/python3s/constant.py#L4-L9

  • 継承クラスを作って
  • マジックメソッド __set__ を潰したのちに
  • しれっとインスタンスを返す
  • デコレータの戻りで、constantitの中身はインスタンスに差し変わってしまう。

もともとのconstantitとして定義したはずのクラスは果たしてどこに行ってしまったのか?
constantitの中身が入れ替わってるので表面上これを参照する方法はない。

実は type(constantit).__mro__ で辿り着けはするが、そこまでするメリットはないだろう。

これでpythonのデコレータの底力の片鱗でも感じていただければ幸いである。

ちなみにデコレータ内部で作るテンポラリなcallableには、名前を "_" にする流派があるようだ。
なかなか風情のある見た目なので真似することにした。

Discussion