2014-04-15 39 views

回答

0

因爲當你在一個裝飾包裹的功能:

@decor 
def test: 

你回來由裝飾,創建函數(living,在這種情況下)不具有相同的docstring等。它不會「丟失」這些數據,living從來沒有!

你可以繞過這與functools.wraps

from functools import wraps 

def decor(fun): 
    @wraps(fun) 
    def living(*args, **kw): 
     ... 
    return func 

快速演示,以證明這一點:

>>> def wrapper(f): 
    def func(*args): 
     """The wrapper func's docstring.""" 
     return f(*args) 
    return func 

>>> @wrapper 
def test(x): 
    """The test func's docstring.""" 
    return x ** 2 

>>> test.__doc__ 
"The wrapper func's docstring." 

>>> from functools import wraps 
>>> def wrapper(f): 
    @wraps(f) 
    def func(*args): 
     """The wrapper func's docstring.""" 
     return f(*args) 
    return func 

>>> @wrapper 
def test(x): 
    """The test func's docstring.""" 
    return x ** 2 

>>> test.__doc__ 
"The test func's docstring." 
+0

謝謝!當使用裝飾器時,當前運行的函數將變爲('living',在這種情況下)並在其中運行'test()'。是對的嗎? – petanne

+0

是的 - 這是正確的 - '@ decor'是'test = decor(測試)'的縮寫' – jonrsharpe

0

這是因爲你的裝飾器基本上取代你的功能。您需要使用functools.wraps()來存儲裝飾的功能內部結構,如__name____doc__。從functools.wraps()的文檔,節省包裝的功能名稱和文檔字符串

>>> def decor(fun): 
...  def living(*args, **kw): 
...   """This is the decorator for living()""" 
...   return fun(*args, **kw) 
...  return living 
... 
>>> @decor 
... def test(): 
...  """function doc""" 
...  pass 
... 
>>> test.__doc__ 
'This is the decorator for living()' 

例子:

您可以輕鬆地通過添加一個文檔字符串你的裝飾功能living()進行測試。

>>> from functools import wraps 
>>> def my_decorator(f): 
...  @wraps(f) 
...  def wrapper(*args, **kwds): 
...   print 'Calling decorated function' 
...   return f(*args, **kwds) 
...  return wrapper 
... 
>>> @my_decorator 
... def example(): 
...  """Docstring""" 
...  print 'Called example function' 
... 
>>> example() 
Calling decorated function 
Called example function 
>>> example.__name__ 
'example' 
>>> example.__doc__ 
'Docstring' 
相關問題