開発ブログ - pythonのデコレータ

pythonのデコレータ

カテゴリ : 
技術メモ » Python
執筆 : 
2017/1/6
いつも書き方忘れるので、ポイントを

デコレータはシンタックスシュガーである

デコレータ構文で書いた場合

@decorator
def func():

デコレータ構文を使わないと

func = decorator(func)
つまり decorator には func が渡されるので基本は

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
  • コメント (0)
  • トラックバック (0)

コメントの投稿

お気軽にコメントください : 投稿されたコメントは承認後に表示されます
プロダクツ

開発ブログ

Link

AD