web-dev-qa-db-ja.com

Python docstringを処理するデコレータ

デコレータで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(およびヘルプ)を取得するための優れたソリューションは何ですか?

48
Günther Jena

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については 標準ライブラリのドキュメント も参照してください。

79
Pär Wieslander

私は解決策を見つけましたが、それが本当に素晴らしいかどうかわかりません:

def decorator(f):
    def _decorator():
        print 'decorator active'
        f()
    _decorator.__name__=f.__name__
    _decorator.__doc__=f.__doc__
    return _decorator

_decorator.__name__=f.__name__の部分は少し恐ろしいようです...どう思いますか?

16
Günther Jena

を見てみましょう functools.wrapshttp://docs.python.org/library/functools.html

2
Mark Byers