2017-04-21 108 views
0

我試圖學習Python中的裝飾器,每次我想我都會遇到類似這樣的問題。我無法弄清楚爲什麼my_func的打印聲明不會顯示,而是我收到'無'返回。如果我在我的包裝中的返回語句中包含funcreturn (func, wrapper)我收到一個錯誤,指出元組對象不可調用。這個例子有什麼問題?爲什麼這個python裝飾器不能打印原始函數的值?

def my_dec(func): 
    def wrapper(): 
     decoration = "decorated" 
     print(decoration) 
    return wrapper 

@my_dec 
def my_func(): 
    a = "Original" 
    print (a) 

print(my_func()) 
+0

您可以通過包括預期和實際輸出來改善您的問題。 – quamrana

回答

4

你永遠叫你wrapper包裹func。添加呼叫,例如:

def my_dec(func): 
    def wrapper(): 
     decoration = "decorated" 
     print(decoration) 
     # Call the decorated function and return what it returns 
     return func() 

    return wrapper 

@my_dec 
def my_func(): 
    a = "Original" 
    print (a) 

print(my_func()) 

現在會產生(因爲func()implicitly returns None):

decorated 
Original 
None 

如果我包括我的return語句func在我的包裝return func, wrapper我得到一個錯誤說的元組對象不可調用。

錯誤一定是來自於你做這樣的事情:

def my_dec(func): 
    def wrapper(): 
     decoration = "decorated" 
     print(decoration) 

    # Now `my_dec` returns a tuple instead of a function 
    return func, wrapper 

記住裝潢is (roughly) equivalent to just doing

def my_func(): 
    ... 

my_func = my_dec(my_func) 

my_dec()裝飾現在返回的元組(func, wrapper),而不是包裝函數,所以當你試圖撥打my_func()時,你實際上試圖「調用」已被分配給my_func的元組。

正如你應該學習如何使用functools.wraps,這是一個方便的功能調用update_wrapper(),其更新包裝功能看起來像FUNC一個很好的措施:

from functools import wraps 

def my_dec(func): 
    @wraps(func) 
    def wrapper(): 
     decoration = "decorated" 
     print(decoration) 
     return func() 

    return wrapper 

沒有了它你」 d獲取:

In [4]: print(my_func.__name__) 
wrapper 

,並與包裝:

In [9]: print(my_func.__name__) 
my_func 

它還複製其他有用的屬性,如__doc__

+0

這對我來說很有意義。非常感謝你。我現在也會去探索functools.wraps。 –

相關問題