にたまごほうれん草アーカイブ

はてなダイアリーで書いてた「にたまごほうれん草」という日記のアーカイブです。現在は「にたまごほうれん草ブログ」を運営中です。

デコレータを使う

クリスマスの休日にやることではないかもしれないが、Pythonのとあるライブラリの中のコードで使われていたついでに調べたのでメモ。
関数の上部に「@デコレータ名」という形式で装飾を付けることで、関数に対して付加的な動作を加えることができるもの。

書き方

下記のdecorator関数のように、関数をネストして内部関数を返すような形で定義すると、some_func関数の上部に「@decorator」としてsome_funcに適用することができるようだ。

#! /usr/bin/env python

def decorator(func):
    def inner(*args):
        return func(*args)+" is decorated"
    return inner

@decorator
def some_func():
    return "some_func"

print some_func()
#=>some_func is decorated

意味としては、

some_func = decorator(some_func)

と同義なので、シンタックスシュガーのひとつだと考えていればよさそう。
複数の関数に対して共通の処理を付加したい場合などに使うのでしょう。
もうひとつの使い方としては、デバッグ時に関数のチューニングのために実行時間を計測したり、などに使えそう。

#! /usr/bin/env python

import time

def measure_time(func):
    def inner(*args):
        start = time.time()
        ret = func(*args)
        end = time.time()
        print "[%s] %f" % (func.__name__, end - start)
        return ret
    return inner

@measure_time
def some_func():
    for i in range(10000000):
        i*i
    return

some_func()