装饰函数返回“无”

时间:2019-04-07 18:07:47

标签: python python-3.x decorator

我是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))  

很抱歉有语法错误,我不是英语为母语的人

3 个答案:

答案 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

对于装饰器,您需要记住它只是一个闭包,带有一些奇特的语法。您仍然需要自己处理函数返回参数。

几个补充:

答案 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