🐕

python3 大量の引数を扱う場合のプラクティス

2023/12/19に公開

大量の引数を扱いたい場合は少なからずある。例えば次のような関数だ。

https://github.com/kamawanu/zenn.dev-kamawanu-codes/blob/main/python3s/massunpack.py#L2-L3

どこかで見たような定義?と思ったなら正しい、これはdataclasses.dataclassデコレータの引数だ。

例示の関数定義自体に意味はないが、大量の引数というテーマについてdataclassデコレータを参照させてもらっただけである。

キーワード引数にするメリットは少なからずある。
引数の意図を逐次確認できるため、順番の入れ違いが起こりにくくなるためだ。

https://github.com/kamawanu/zenn.dev-kamawanu-codes/blob/main/python3s/massunpack.py#L5

送る方、受け取る方。数々のメリットがあるキーワード引数だが、この通り数が大きくなると、結局煩雑になってしまう。(原典であるdataclassデコレータの場合は、キーワードを全て使う状況はまれなため、このまま十分やっていける。)

dataclassに詰め替える

例によってdataclassを使う方法を考えた。

https://github.com/kamawanu/zenn.dev-kamawanu-codes/blob/main/python3s/massunpack.py#L5

kw_only=Trueでキーワード引数をそのまま受け取れるし、引数の過不足はdataclassがエラーにしてくれる。仲介は、unpack operatorが使えるため、タイプミスの心配もない。

呼び出す側の使い勝手は変わってない。

dataclass 版引数を直接受け取れるようにしてみる

もうちょっと突き詰めて、前出のdataclassを直接受け取るような仕掛けも付け加えてみる。

https://github.com/kamawanu/zenn.dev-kamawanu-codes/blob/main/python3s/massunpack.py#L29-L35

これだけだともちろんメリットは余りない。

クラスの __init__

classの初期化に使う場合を考えてみよう。

https://github.com/kamawanu/zenn.dev-kamawanu-codes/blob/main/python3s/massunpack.py#L37-L40

考えられるメリットは次の点

  • __init__であれこれ変数を詰め替える手間が省ける
  • 他のインスタンスに引数群を渡す場合、self.configをそのまま渡すことができる。
    • selfをそのまま渡すより、副作用の見積りがしやすい。
  • メンバ変数の意図によって隔離をする

結果的に self.XXX と書けば済んだはずの箇所が全て、self.config.XXX にしなければならなくなったのだが、これはIDEが補完してくれるので、大きなデメリットにはならないと考えている。

Discussion