知られていない機能 デコレータ

 『みんなのPython』には載ってないので知らなかったのですが、インターネットでPyhtonのコードを見ていると@propertyとか、@classmethod、@staticmethodなんて記述がありました。この機能はデコータと呼ばれる機能らしいです。この機能について説明したいと思います。

 デコレータとは

 デコレータとは関数を別の関数に置き換えて、機能を付加しようという考えから生まれたもののようです。

 まず関数の置き換えの部分を見てみるとこんな感じです。

@deco
def foo(): pass

は要約すると

foo = deco(foo)

と同じ意味になる。つまりfoo()を呼んでも、デコレートされたfooが呼び出される。
使ってみるとこんな感じ

#coding: shift-jis

def deco(func):
  return "deco Functionが表示されます。"

@deco
def foo():
  return "foo Functionは表示されません。"

print foo
raw_input()

出力画面
 deco Functionが表示されます。
 foo関数にラッピングを掛けて全く別の機能にしているみたい。こんな機能、どんな意味があるのだろうと思いましたが、実際には次のように使い、関数に機能を付加することが出来ます。

#coding: shift-jis

def deco(func):
  def wrap(*args, **kwargs):
    print args ←引数の中身の確認
    print kwargs ←空の辞書になっているはず。
    print "%sの出力:%s" % (func.__name__, func(*args, **kwargs))
  return wrap ←ここでwrap関数を実行。

@deco
def sqrt(a,b):
  return a**(b)

sqrt(3,0.5)
raw_input()

出力画面:
 (3, 0.5)
 {}
 sqrtの出力:1.73205080757
 これなら、デコレータの言葉の意味も判る気がしますね。ついでに引数の受け渡し方もわかるように書いてみました。