Pythonのデコレータ
Pythonの@で書かれているアレ
非常にややこしいMijinko_SD.icon
前のサンプルに追記しながら次のサンプルを書くので、可能な限り一番上から読んで欲しい
#Pythonの構文
引数なし
code:py
def deco(func):
print("~~デコ~~")
func()
print("~~デコ~~")
@deco
def decorare():
print("デコられたぜ")
code:コンソール
~~デコ~~
デコられたぜ
~~デコ~~
関数の前に@decoを書くことで、decorare関数をdecoに渡している
渡した関数は、deco関数内ではfuncという名前で呼び出すことができる
内部的な呼び出し順
ぱっと見でわかる人向け
わからない人はコールバック関数あたりを勉強してみるといいかも
code:py
# 後々のコードとフォーマットを合わせるため、わざと冗長に書いている
deco_deco = deco(decorare)
deco_deco()
引数あり
引数ありのデコレータ
code:py
def deco(hikisu):
def deco_deco(func):
print(f"~~デコ({hikisu})~~")
func()
print("~~デコ~~")
return deco_deco
@deco("デコレータ引数")
def decorare():
print("デコられたぜ")
code:コンソール
~~デコ(デコレータ引数)~~
デコられたぜ
~~デコ~~
よくわからんが、@deco("デコレータ引数")と書くと、deco(hikisu)の戻り値(return)に指定されているdeco_decoがデコレータとして機能するらしい
@deco_decoに置き換えられていると考えても良いかも
内部的な呼び出し順
code:py
deco_deco = deco("デコレータ引数")
deco_deco(decorare)
さらにデコられ側にも引数を持たせる
デコレータ側から、デコられ側に値を渡す
code:py
def deco(hikisu):
def deco_deco(func):
print(f"~~デコ({hikisu})~~")
func("デコられに値を渡してデコったぜ")
print("~~デコ~~")
return deco_deco
@deco("デコレータ引数")
def decorare(decorare_hikisu):
print(decorare_hikisu)
code:コンソール
~~デコ(デコレータ引数)~~
デコられに値を渡してデコったぜ
~~デコ~~
内部的な呼び出し順
あくまでdecoの内部処理が変わっただけなので、ここのコードは前の項と全く同じ
code:py
deco_deco = deco("デコレータ引数")
deco_deco(decorare)
デコられ側を普通に関数として呼び出せるようにする
察しの良い人は気づいているかもだけど、今までのサンプルは関数を定義しているだけなのに勝手に呼び出されていた
ちなみに、普通に関数を呼ぼうとしても、エラーを吐く
なので、勝手に呼び出されずにdecorare()と書いた時に呼び出せるようにする
code:py
def deco(hikisu):
def deco_deco(func):
def ataiwo_watasu(decorare_hikisu):
print(f"~~デコ({hikisu})~~")
func(decorare_hikisu)
print("~~デコ~~")
return ataiwo_watasu
return deco_deco
@deco("デコレータ引数")
def decorare(decorare_hikisu):
print(decorare_hikisu)
decorare("デコられに引数を渡すよ")
code:コンソール
~~デコ(デコレータ引数)~~
デコられに引数を渡すよ
~~デコ~~
内部的な呼び出し順
code:py
deco_deco = deco("デコレータ引数")
ataiwo_watasu = deco_deco(decorare)
ataiwo_watasu("デコられに引数を渡すよ")
参考
Python Tips: デコレータに引数を渡したい - Life with Python