White scenery @showyou, hatena

If you have any comments, you may also send twitter @shsub or @showyou.

デコレータ関数

某所で

@hoge
def foo:

って何かなぁって調べたりきいたりしたところ、デコレート関数っていうらしい。

以下ソースはhttp://jutememo.blogspot.com/2008/10/python-1_09.htmlから引用。

def D(f):
    print u"デコレータが実行された"
    return f

def hoge():
    print "hoge"

hoge = D(hoge)
hoge()

結果

デコレータが実行された
hoge

これを見て、hogeを呼ぶとD(hoge)になり、このあと何回呼んでも「デコレータが実行された」と表示されるのかとおもったら違った。
どうやらhoge=D(hoge)の時点でD(hoge)は評価され、「デコレータが(ry」と表示される。

デコレータを使っても同様。

def D(f):
    print u"デコレータが実行された"
    return f

# デコレータを適用したときに、関数 D が適用される。
@D
def hoge():
    print "hoge"

hoge()

これだとhoge関数の定義が終わったところ(9行目)でD(hoge)の評価が行われる。

これだけだとせめて、関数が何回くらいか定義されたか、程度しかわからないが、内部関数を作ってそれをデコレータの戻り値にすると

def D(f):
    def _():
        print "*--" * 10
        f()
        print "--*" * 10
    return _

@D
def hoge():
    print "hoge"

hoge()

@D
def piyo():
    print "piyo"
  

piyo()

hoge()とかpiyo()を何度呼んでも常に"*--" * 10が入るようになる