修饰函数返回“None”

2024-04-27 05:02:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我对python非常陌生,我刚刚遇到了decorators。我仍然有点困惑他们,但我正在学习

我试图制作一个decorator,告诉我函数完成所花的时间,但显然,当我尝试在一个应该返回某些内容的函数上使用它时,它只返回“None”

关于这个问题,我只见过几个问题,但没有一个真正有用

这是我的密码

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

对不起,有语法错误,我不是以英语为母语的人


Tags: 函数innewmakethattimedefargs
3条回答

decorator用wrapper替换squarewrapper不返回任何内容。它应该返回包装函数返回的值。你知道吗

这是正确的方法:

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

我改变了三件事:

  • 添加return,以便从修饰函数返回值
  • 添加了**kwargsfunc调用,因为如果使用不同,可能需要它
  • 添加了try/finally块,这样即使在出现异常的情况下也会进行打印输出,而且这使得返回值更容易。你知道吗

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

问题是没有返回内部函数返回值。变化如下:

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

对于decorator,您需要记住它只是一个闭包,具有一些奇特的语法。您仍然需要自己处理函数返回参数。你知道吗

一些补充:

相关问题 更多 >