pythonのデコレータ
2016/01/15
pythonのデコレータについてのメモ。
関数とかの上に良く見かける「@xxx」みたいなやつ。
こいつができた経緯は「エキスパートPythonプログラミング」のP76によると下記のような動機からのようです。
クラスメソッドや静的なメソッドを定義する際に、メソッド定義の前の行にすっきりと書けるようにしたい
デコレータを使用しない場合
class SayHellow(): def say_good_morning(self): print "Good Morning!" say_good_morning = classmethod(say_good_morning) >>SayHellow.say_good_morning() Good Morning!
Python2.3まではsay_good_morningメソッドをSayHellowクラスのクラスメソッドにするには、上記のようにする必要があったようですが、Python2.4で追加されたデコレータを利用すれば下記のようになり、読みやすくなります。
デコレータを使用した場合
class SayHellow(): @classmethod def say_good_morning(self): print "Good Morning" >>SayHellow.say_good_morning() Good Morning!
自分でデコレータを作る場合
「エキスパートPythonプログラミング」のP77によると、
デコレータ関数の中で、元の関数を呼び出すサブ関数を定義し、それを返すという方法がもっともシンプルで読みやすいでしょう。
とのこと。
@add_everyone def good_evening(): return "Good Evening!" Good Evening! Everyone.
上記の@add_everyoneデコレータは、good_evening関数が返す「Good Evening!」の後ろに「Everyone.」をつけてprintするデコレータとすると、下記のように@add_everyoneデコレータは実装される。
def add_everyone(func): def _deco(): print func() + "Everyone." return _deco
funcにはデコレータをつけた関数が入るので、ここではgood_eveningが入ることになる
つまり、@add_everyoneをつけたgood_evening関数は、add_everyone関数の引数として代入され、good_evening関数がreturnした「Good Evening!」に「Everyone.」を足してprintするので下記のようなイメージ。
def add_everyone(good_evening): def _deco(): print good_evening() + "Everyone." # good_eveningは「Good Evening!」を返す。 return _deco