2017-04-21 31 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。 –

相关问题