デコレータでdocstringを使用する際に問題が発生しました。次の例を考えます。
def decorator(f):
def _decorator():
print 'decorator active'
f()
return _decorator
@decorator
def foo():
'''the magic foo function'''
print 'this is function foo'
help(foo)
これで、ヘルプにfoo
のdocstringが期待どおりに表示されなくなり、次のように表示されます。
Help on function _decorator in module __main__:
_decorator()
デコレータがなければ、ヘルプは正しいです:
Help on function foo in module __main__:
foo()
the magic foo function
関数foo
はデコレータによってラップされているので、関数オブジェクトは関数foo
ではなくなりました。しかし、期待どおりにdocstring(およびヘルプ)を取得するための優れたソリューションは何ですか?
functools.wraps()
を使用して、デコレータの属性を更新します。
from functools import wraps
def decorator(f):
@wraps(f)
def _decorator():
print 'decorator active'
f()
return _decorator
@decorator
def foo():
'''the magic foo function'''
print 'this is function foo'
help(foo)
functools
については 標準ライブラリのドキュメント も参照してください。
私は解決策を見つけましたが、それが本当に素晴らしいかどうかわかりません:
def decorator(f):
def _decorator():
print 'decorator active'
f()
_decorator.__name__=f.__name__
_decorator.__doc__=f.__doc__
return _decorator
_decorator.__name__=f.__name__
の部分は少し恐ろしいようです...どう思いますか?
を見てみましょう functools.wraps
: http://docs.python.org/library/functools.html