開発ブログ - pythonのデコレータ
いつも書き方忘れるので、ポイントを
デコレータはシンタックスシュガーである
デコレータ構文で書いた場合
デコレータ構文を使わないと
デコレータはシンタックスシュガーである
デコレータ構文で書いた場合
@decorator
def func():
デコレータ構文を使わないと
func = decorator(func)
つまり decorator には func が渡されるので基本は
この時 _wrap(...) が実際の func になることがポイント
たとえば、本来パラメタとして数値が文字列で渡される関数なのだが、数値としてパラメタが渡るようにするデコレータは、以下のような形で処理できる
■要するに
単純に言えば、処理したい関数を書く
それをデコレータの名前を付けた func を引数とした関数でくるむ
という感じ
■デコレータへの引数
デコレータに引数を付けたい場合、基本の部分にさらに引数を受け取る部分でくるむ感じになる。
展開すると
となる
そのため、引数を受け取る部分でくるんであげればOK
TIPS1
デコレータは多重に設定することができる
この場合も、順番に考えれば大丈夫
func1 = deco1(deco2(func1))
def decorator(func):
def _wrap(*args, **kw):
# do something
func(*args, **kw)
return _wrap
この時 _wrap(...) が実際の func になることがポイント
たとえば、本来パラメタとして数値が文字列で渡される関数なのだが、数値としてパラメタが渡るようにするデコレータは、以下のような形で処理できる
def int_param(func):
def _wrap(s):
v = int(s)
func(v)
return _wrap
@int_param
add1(v):
return v+1
■要するに
単純に言えば、処理したい関数を書く
def _wrap(arg1, arg2):
# do something
return func(func_arg1, func_arg2, ...)
それをデコレータの名前を付けた func を引数とした関数でくるむ
def decorator(func):
def _wrap(...)
...
return _wrap
という感じ
■デコレータへの引数
デコレータに引数を付けたい場合、基本の部分にさらに引数を受け取る部分でくるむ感じになる。
@decorator('deco_arg')
def func():
展開すると
func = decorator('deco_arg')(func)
となる
そのため、引数を受け取る部分でくるんであげればOK
def decorator(deco_arg):
def _decorator(func):
def _wrap(*args, **kw):
# do something
return func(*args, **kw)
return _wrap
return _decorator
TIPS1
デコレータは多重に設定することができる
@deco1
@deco2
def func1():
この場合も、順番に考えれば大丈夫
func1 = deco1(deco2(func1))
def deco1(func):
def _wrap(*args, **kw)
print "deco1"
return func(*args, **kw)
return _wrap
def deco2(func):
def _wrap(*args, **kw)
print "deco2"
return func(*args, **kw)
return _wrap