2009-04-27
■[Python]デコレータを書く時にはfunctools.wrapsを使おう
トリビアルな例だが、元の関数(func)をデコレート・ラップするmydecoratorというデコレータを書いた時、下のように単純にinnerを返すと、
def mydecorator(func): def inner(*args, **kwds): print "Hi, I'm inner!" return func(*args, **kwds) return inner @mydecorator def hello(to): """ Say hello to somebody """ print "Hello, %s!" % to if __name__ == '__main__': print repr(hello) print hello.__doc__
結果として、
<function inner at 0xb7e6edf4> None
のように、デコレートされた元の関数(hello)の関数名やドキュメント文字列が失われてしまう。
デコレータを書くたびに「もっときちんと書かないとなー」と思いつつも手を抜いていたが、Python2.5以降ならばfunctools.wrapsを使えばよいということを知った。
上のコードをfunctools.wrapsで書き直せば次の通り。
from functools import wraps def mydecorator(func): def inner(*args, **kwds): print "Hi, I'm inner!" return func(*args, **kwds) return wraps(func)(inner) @mydecorator def hello(to): """Say hello to somebody""" print "Hello, %s!" % to if __name__ == '__main__': print repr(hello) print hello.__doc__
元の関数名もドキュメント文字列も失われない。
<function hello at 0xb7eb60d4> Say hello to somebody
リンク元
- 38 http://reader.livedoor.com/reader/
- 22 http://www.google.com/reader/view/
- 19 http://www.google.co.jp/search?sourceid=chrome&ie=UTF-8&q=functools
- 17 http://d.hatena.ne.jp/
- 16 http://d.hatena.ne.jp/johzan/
- 15 http://www.google.co.jp/search?hl=ja&q=ubuntu+usb+インストール&lr=&aq=7&oq=ubu
- 13 http://www.google.co.jp/search?hl=ja&client=firefox-a&rls=org.mozilla:ja-JP-mac:official&num=50&newwindow=1&q=from+pkg_resources+import+load_entry_point&btnG=検索&lr=lang_ja
- 12 http://www.google.co.jp/search?q=functools&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:ja:official&client=firefox-a
- 12 http://www.google.co.jp/search?sourceid=navclient&hl=ja&ie=UTF-8&rlz=1T4GFRD_jaJP309JP309&q=内部エンコーディング:UTF-8
- 11 http://boxheadroom.com/2009/04/25/py_eval_exec_closure