デコレータは関数を返す関数として作ります。
from typing import Callable
def deco(f: Callable) -> Callable:
...
return wrapper
関数にデコレータをつけると、関数が置き換わります。
def just_print():
print("ha.")
just_print() # just_print が呼ばれる。
@deco
def just_print2():
print("haha.")
just_print2() # wrapper が呼ばれる。
wrapper の中では通常、第一引数で受け取った関数を実行します。
# ... の中身
def wrapper(): # 必要に応じて引数 *args, **kwargs
# ~~~ 前処理 ~~~
retval = f()
# ~~~ 後処理 ~~~
return retval
以上。
おまけ
関数を返せばいいのでクラスでも書けます。クラス変数とかインスタンス変数が使えて便利?(煩雑?)
from typing import Callable
class Deco():
@staticmethod
def deco(f: Callable) -> Callable:
...
return wrapper
@Deco.deco
def just_print3():
print("hahaha.")
just_print3() # Deco.deco の wrapper が呼ばれる。
クラスを装飾するデコレータを書くこともできます。
def class_deco(c: Type) -> Type:
class wrapper_class(c): ...
return wrapper_class