デコレーターについて
2023-04-16
デコレーターの機能
デコレーターは関数の振る舞いを装飾する関数。例えば関数A, B, CがあってBをAで装飾した関数をCとすれば、CはBの実行をAで制御ができるということになる。具体的な制御だとAによって「Bの前後で処理を入れてBの実行時間を測定する」「Bを複数回実行する」「条件分岐でBを実行する」ということができる。
これならBを直接編集すれば済むと思うが、B以外の関数にも適応しなければならないとなるとどうだろうか?全部書き換えることになるので面倒になる。それに編集し続けるより新しく装飾された関数を用意したほうが用途に合わせて実行できる上に管理がしやすい。Bがそもそも編集できない場合もある。
デコレーター導入のきっかけ
前処理や実行後に追加で処理する必要があったとかじゃなくて、デコレーターによって関数を実行しないようにしたかった。実行しない理由はテスト関数の導入でもうテストする必要がないものを簡単に指定したかったから。引数にフラグをつけて、フラグをもとに実行の制御をするのも、引数を入れるのは大変。後になって気付いた。
デコレートのやり方
とても簡単で、ある関数をスキップすれば良いので
def skip_decoration(function):
def wrap():
pass
return wrap()
とする。引数にあるfunction
が装飾される方の関数で、wrap()
が装飾する方の関数。本来であればwrap()
の引数にfunction
を入れてwrap()
内でさまざまな処理を施すが今回はスキップしたいだけなので何もしない。そして最後に返り値としてwrap()
を指定する。
あとは装飾したい関数の上に@skip_decoration
とするだけで良い。こうすると勝手に装飾された関数がデコレーターに代入される仕組みがある。
返り値にwrap()
としているが、wrap
とすることで即実行しないようにもできる。()とすればデコレートした瞬間に実行してしまう。