繁体   English   中英

装饰函数返回“无”

[英]Decorated function returns “None”

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

抱歉,没有任何语法错误,我不是英语母语人士

装饰器将square替换为wrapperwrapper器不返回任何内容。 它应该返回包装函数返回的值。

这是正确的方法:

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 ,以便从装饰函数返回值
  • func调用中添加了**kwargs ,因为如果使用不同的方法可能需要
  • 添加了try / finally块,以便即使在发生异常的情况下也可以进行打印输出,而且这使得返回值更加容易。

问题是您的内部函数返回值没有被返回。 更改记录如下:

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

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

一些补充:

装饰的函数不会显式返回任何内容-因此,默认情况下,它返回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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM