Search on the blog

2015年2月5日木曜日

Pythonのデコレータで遊ぶ

 Pythonのデコレータで遊んでみた。Javaのアノテーションでアスペクトを挿入するようなイメージに近いのかなと思った。Pythonのデコレータの方がお手軽感がある。

関数の実行前後にログを出す
まず考えてみた例。関数の実行前と実行後に関数名 + "begin/end."と表示させるデコレータ。
def log(f):
    def _f():
        print "%s begin." % (f.__name__)
        f()
        print "%s end." % (f.__name__)
    return _f 

@log
def func():
    pass

if __name__ == '__main__':
    func()

関数をn回繰り返す
次に考えた例。
受け取った数だけ関数を繰り返し実行するデコレータを返す関数を使って、こんなこと出来るのだろうかと思ったら出来た。
def repeat(n):
    def _repeat(f):
        def _f():
            for _ in range(n):
                f()
        return _f
    
    return _repeat

@repeat(5)
def sayHello():
    print "Hello!"

if __name__ == '__main__':
    sayHello()

再帰関数をメモ化する
最後。可変長リストを使って、任意の再帰関数をメモ化するデコレータ。
def memorize(f):
    cache = {}
    def _f(*args):
        if args not in cache:
            cache[args] = f(*args)
        return cache[args]
    return _f

@memorize
def tarai(x, y, z):
    if x <= y:
        return y
    return tarai(tarai(x-1,y,z), tarai(y-1,z,x), tarai(z-1,x,y))

@memorize
def fib(n):
    if n < 2:
        return n
    return fib(n-1) + fib(n-2)

if __name__ == '__main__':
    print fib(100)
    print tarai(100, 50, 0)

0 件のコメント:

コメントを投稿