pythonでは、@hogehoge というデコレータを関数 func
の定義の前に置くことで、func()呼び出しに hogehoge()
関数で定義した動作を追加できます
例えば次の例
def hogehoge(f):
def _wrapper(*args, **kwargs):
print(f'hogehoge._wrapper(): デコレータが呼び出されました: args={args} kwargs={kwargs}')
print(f'hogehoge._wrapper(): 関数 f を呼び出します')
v = f(*args, **kwargs)
print(f'hogehoge._wrapper(): 関数 f の戻り値: {v}')
return v
return _wrapper
@hogehoge
def func(*args, **kwargs):
print(f"funcが呼び出されました")
print(f" args=", *args)
print(f" kwargs=", kwargs)
return 1.0
func(3.0, a = 'abc')
は、
hogehoge(func)(3.0, a = 'abc')
# f = hogehoge(func) # <= hogehoge._wrapper()関数の参照が
f に入る
# f(3.0, a = 'abc') # <= hogehoge._wapper(*args, **kwargs)
関数が呼び出される。
# *args と **kwargsは func(3.0, a = 'abc') に渡された位置引数 3.0 と
# キーワード引数 {"a": 'abc'} に対応
あるいは
print(f'hogehoge._wrapper(): デコレータが呼び出されました: args={args} kwargs={kwargs}')
print(f'hogehoge._wrapper(): 関数 f を呼び出します')
v = hogehoge(3.0, a= 'abc')
print(f'hogehoge._wrapper(): 関数 f の戻り値: {v}')
return v
と同じ動作をします(異なる書き方で同じ動作をすることを
Syntax sugar であるといいます)。
つまり、hogehoge(func)は hogehoge._wrapper()
関数を返すので、
hogehoge(func)(3.0, a = 'abc') により hogehoge._wrapper(3.0, a = 'abc')
が呼び出されます。
hogehoge._wrapper(3.0, a = 'abc') 内ではfunc(3.0, a = 'abc')を呼び出していますが、その前後に追加処理を行っています。
デコレータは、このような共通の追加処理を関数に追加するための仕組みです。
Plotly Dashの場合、@app.callback() の app は
app = Dash(__name__)
と、Dashの変数になっており、@app.callback の実体は Dashクラスで定義されている .callback() 関数です。