オープンソースで実装されているアルゴリズムを、ライセンスを確かめたうえで、自分なりに使いこなしてみよう。
想定する読者: 中級レベル
ふだんから、最新版のPythonの機能を活用しきっている人にとっては、何をいまさらという内容しか書いていません。
前提:
Python3
自分なりの改変の常套手段
不必要なimport をなくす。
- 高機能な開発環境(例: pycharm)の場合だと、不必要なimportがあると表示で区別してくれる。
- 不必要なimportは、そのプログラムの動作環境を無駄に狭めてしまう。
- 使っていないライブラリのために、動作環境を狭めてしまうことはやめよう。
- 参考: 言語によっては不必要なimportがあるとビルドに失敗する言語もある。
from モジュール import *
をなくす
- モジュールからすべてをimportするのは、変数・関数などの由来を不明にしてしまうので止める。
- from モジュール import 識別子1, 識別子2と書き換えていく。
-
from モジュール import *
をなくしたことで、参照できなくなった識別子を見つけて、それを明示的にimport していく。 - そうすると、
from モジュール import *
をなくすことができる。
コマンドラインの引数の処理には argparse
を使う。
- ハードコーディングされている入力も
argparse
で処理するようにする。 - 従来の
sys.argv
を使ったif文での条件分岐を置き換える。 - 同様に
getopt
よりも、argparse
を使う。 - defaultを活用する。
あるいはコマンドラインの引数の処理にabsl
を使う
https://abseil.io/docs/python/guides/flags
このライブラリもコマンドラインの引数を行なうライブラリである。
argpareseでヘルプを表示させたときだと、デフォルト値の表示がされないが、
abslでのヘルプの場合だと、デフォルト値の表示がされるという特徴がある。
適度にモジュール化する。
- その機能を他のプログラムから再利用しやすくするために、適度にモジュール化する。
- その機能を使うために見えなきゃいけない変数と、使うだけの分には知らなくてよい変数とに分離する。
- 関数やメソッドを抽出しよう。
type hintを利用しよう
def read_image(p):
return somefunc(p)
よりは
def read_image(p: Path) -> np.ndarray:
return somefunc(p)
と書くと、入力と出力のデータの型が明確になるので、人にとっても理解しやすいものになる。
非公開の関数、変数は_で始める。
その機能を使う上で、import する必要のない関数、変数などは_(アンダースコア)で始まる名前にする。
- そうすることで、再利用する際に間違った使い方をすることを予防できる。
### 初期化・実行・終了処理をもつような機能の一群はclassを用いた実装に変える。
-
dataclass
を用いた実装を選ぶ - 初期化プロセスには
__post_init__
を活用する。 - 参考にするよい実装をまねて、メソッドを設計する。
- 目的が同じライブラリなら、同じインタフェースになるようにメソッドを設計しよう。
- 例:scikit-learnの機械学習のライブラリは、さまざまなアルゴリズムに対して同一のインターフェースでfit()とpredict()をできるようにしている。そのことがさまざまなアルゴリズムを簡単に切り替えて、アルゴリズムを利用可能にしている。
モジュール化・classを用いた実装にしたあとの状況
-
機能を適度にモジュール化したあとは、その機能を利用するのに、import もしくは
from モジュール import 識別子
する対象は とても少なくなっているはずだ。 -
また、その機能を使う側のコードはとても簡潔になっているはずだ。
-
それでいて、細かい設定を必要とする場合には指定できる。