Pythonには「デコレータ」(decorator) という機能が標準で提供されています。
デコレータはPython以外のプログラミング言語ではあまり見ないので、少々とっつきにくい印象を受けます。
このエントリでは、Pythonのデコレータについて説明し、その使い方を紹介します。
デコレータとは「関数を受け取って関数を返す関数」です。
関数fは関数gを受け取って関数g'を返している
プログラミングにおいては「関数を受け取る関数」や「関数を返す関数」のことを高階関数と言います。
コードでデコレータの例を見てみましょう。
Pythonでデコレータを定義するにはfunctools
からwraps
関数をインポートします。
from functools import wraps
def to_john(f):
@wraps(f)
def wrapper():
return f() + ' John!'
return wrapper
@to_john
def say_hello():
return 'Hello!'
上記の例で、to_john()
関数がデコレータです。
to_john()
関数は引数f
を受け取り、内部で定義したwrapper()
関数を返しています。
wrapper()
関数は、引数f
をf()
のようにして関数呼び出しし、f()
の戻り値と' John!'
と結合した結果を返しています。
このことから、デコレータの条件のうち「関数を返す関数」であるというのはわかりました。
しかしデコレータは「関数を受け取る関数」でもあります。
「受け取る関数」はどこで定義しているのでしょうか?
デコレータを使って関数をデコレート(decorate/修飾)するには、修飾したい関数の上に@decorator
のように表記します。
@to_john
def say_hello():
return 'Hello!'
例では、デコレータ@to_john
がsay_hello()
関数をデコレートしています。
つまり、デコレータto_john(f)
の引数f
の正体は、デコレートされる関数(この場合はsay_hello()
)であるというわけです。
>>> say_hello()
Hello! John!
ところで@wraps(f)
は何をしているのでしょうか?
wraps
デコレータは、内部的にデコレータ関数(wrapper関数)がデコレートされる側の関数(wrapped関数)に見えるようにしています。
これは、デコレータ関数でエラーが発生した場合などに役立ちます。
詳しくは下記をご覧ください。
以上です。このエントリでは、Pythonのデコレータについて説明し、その使い方を紹介しました。
コメントを送る
コメントはブログオーナーのみ閲覧できます