blog.monophile.net

Takaaki Yamamoto

東京工業大学において計算機科学と応用数学を学び、情報科学芸術大学院大学[IAMAS]においてメディア表現を専攻し修了。 現在は digitiminimi Inc. において、インフラエンジニアとして生計をたててている。 また、計算を主題に制作を行い、現代音楽作品や公共インスタレーション作品など技術提供を行う。 三輪眞弘に師事する。

List

pythonでデコレータ

pythonでデコレータをよく理解したいな、ということで、簡単なサンプルを書いてみました。 関数が呼び出されるたびに関数の名前と関数の記述されているファイル名と行数と引き数を表示するデコレータです。

deco_test.py

# debugというbooleanの引き数を取るデコレータを作る関数を定義
def deco_gen(debug):
    def deco(func):
        f = dict()
        f['fname']  = func.func_name
        f['file']   = func.func_code.co_filename
        f['lineno'] = func.func_code.co_firstlineno
        def wrap(*args,**kw):
            if debug:
                arg = { 'args':args,'kw':kw }
                print "[ %s, %s ]" % ( f, arg )
            return func(*args,**kw)
        return wrap
    return deco

# テスト用の関数
debug = True
@deco_gen(debug)
def hoge(*args, **kw):
    return args, kw

if __name__ == "__main__":
    print hoge(0, 1, foo="foo")

以下が上記のコードを実行した時の出力です。 赤文字のところがデコレータが装飾した部分ですね。

 [ {'file': 'deco_test.py', 'fname': 'hoge', 'lineno': 16}, {'args': (0, 1), 'kw': {'foo': 'foo'}} ]
((0, 1), {'foo': 'foo'})

デコレータというのは結局のところ、 関数を引き数に取り新しい関数を出力する関数とそれのためのシンタックスシュガーなんですね。 っていう一文にまとめても、理解しにくいだけですね。