2009-11-23 21 views
40

我在裝飾器中使用docstrings時遇到問題。考慮下面的例子:Python裝飾器處理文檔字符串

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文檔字符串如預期,它表明:

Help on function _decorator in module __main__: 

_decorator() 

沒有裝飾,幫助是正確的:

Help on function foo in module __main__: 

foo() 
    the magic foo function 

我知道,函數foo被修飾器封裝,所以函數對象不再是函數foo。但是,按照預期獲得文檔字符串(和幫助)的好方法是什麼?

回答

62

使用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) 

另見Standard Library documentationfunctools

+0

如果'foo'帶有任何參數,這不起作用 - 它們會被_decorator使用的任何東西替換。這是一個問題,尤其是當你想讓你的裝飾器使用'* args,** kwds'時。我從來沒有能夠找到一種方法來使用'functools.wraps'來使文檔字符串正確。 – 2009-11-23 12:53:46

+3

@Scott Griffiths:即使'foo'帶有參數,docstring仍然是正確的。但是,'help(foo)'會顯示'_decorator'的參數列表,因爲它實際上代替了'foo'函數。如果你正在編寫使用'* args,** kwargs'的任意參數的裝飾器,沒有什麼好辦法,但是對我來說重要的一點是文檔字符串保持不變。爲了清楚起見,可以始終在文檔字符串中指定參數詳細信息。 – 2009-11-23 13:05:50

+0

感謝您的額外信息。我最近一直無法得到正確的裝飾功能的幫助描述 - 這似乎是一個相當糟糕的事態,但我明白這個困難,因爲裝飾後的功能可能具有完全不同的簽名。不過,一定有辦法...... :) – 2009-11-23 14:27:29

12

我找到了解決辦法,但不知道它是否真的很高興:

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

_decorator.__name__=f.__name__的部分似乎有點可怕......你覺得呢?

+4

事實上,這是(幾乎?)正是functools.wraps做:) – thomas 2009-11-23 15:08:50

+2

它看起來並不可怕給我。它確切地說明了你想說的話。 「我希望這個函數的名字是'myfunction'而不是'_decorator'。」 – jcdyer 2009-11-23 16:20:19

-5

現在可能是一個有點老,但你這是怎麼做到這一點。只要確保@decorator是在同一行縮進爲def decorator(f)

from functools import wraps 

def decorator(f): 
    @wraps(f) 
    def _decorator(): 
     print 'decorator active' 
     return f() 
    return _decorator 

@decorator 
def foo(): 
    '''the magic foo function''' 
    print 'this is function foo' 

help(foo) 
+8

這只是迴應已經接受的答案。 – 2012-10-20 20:42:10