我是python的新手,我刚遇到装饰器。我仍然对他们感到困惑,但我正在学习
我试图做一个装饰器,告诉我函数完成所需的时间,但是很显然,当我尝试在应该返回某些东西的函数上使用它时,它只会返回“无”。
我只看到了几个有关此问题的问题,但没有一个真正有用的
这是我的代码
import time
def time_it(func): # Here i make a simple decorator function that should time my decorated function
def wrapper(*args, **kwargs):
t1 = time.time()
func(*args)
t2 = time.time()
total = t2 - t1
print("The function '" + func.__name__ + "' took", str(total)[0:5], "seconds to complete")
return wrapper
@time_it
def square(nums): # I make a function that squares every number in a list
new_list = []
for n in nums:
new_list.append(n ** 2)
return new_list
lis = [f for f in range(200000)] # i make a list with a range of 200000
print(square(lis))
很抱歉有语法错误,我不是英语为母语的人
答案 0 :(得分:3)
装饰器将square
替换为wrapper
,而wrapper
不返回任何内容。它应该返回包装函数返回的值。
这是正确的方法:
def time_it(func):
def wrapper(*args, **kwargs):
t1 = time.time()
try:
return func(*args, **kwargs)
finally:
t2 = time.time()
total = t2 - t1
print("The function '" + func.__name__ + "' took", str(total)[0:5], "seconds to complete")
return wrapper
我更改了3件事:
return
,以便从修饰后的函数返回该值**kwargs
添加到了func
呼叫中,因为如果使用不同的话可能会需要try
/ finally
块,因此即使出现异常也可以进行打印输出,而且这使得返回值更加容易。答案 1 :(得分:3)
问题在于您的内部函数返回值未返回。更改记录如下:
from functools import wraps
def time_it(func): # Here i make a simple decorator function that should time my decorated function
@wraps(func)
def wrapper(*args, **kwargs):
t1 = time.time()
## Note the change on this line -- I now store the return result from the called function
result = func(*args, **kwargs)
t2 = time.time()
total = t2 - t1
print("The function '" + func.__name__ + "' took", str(total)[0:5], "seconds to complete")
## And then explicitly return the result
return result
return wrapper
对于装饰器,您需要记住它只是一个闭包,带有一些奇特的语法。您仍然需要自己处理函数返回参数。
几个补充:
from functools import wraps
和@wraps(func)
答案 2 :(得分:0)
您的修饰函数不会显式返回任何内容-因此,默认情况下,它返回None
。
您可以在打印时间之前捕获输出,并在最后返回:
def time_it(func): # Here i make a simple decorator function that should time my decorated function
def wrapper(*args, **kwargs):
t1 = time.time()
out = func(*args)
t2 = time.time()
total = t2 - t1
print("The function '" + func.__name__ + "' took", str(total)[0:5], "seconds to complete")
return out
return wrapper