首页 > 解决方案 > python装饰器修改的函数返回值是否只能为Nonetype

问题描述

我写了一个获取程序运行时的装饰器,但是函数返回值变成了Nonetype。

def gettime(func):
    def wrapper(*args, **kw):
        t1 = time.time()
        func(*args, **kw)
        t2 = time.time()
        t = (t2-t1)*1000
        print("%s run time is: %.5f ms"%(func.__name__, t))

    return wrapper

如果我不使用装饰器,则返回值是正确的。

A = np.random.randint(0,100,size=(100, 100))
B = np.random.randint(0,100,size=(100, 100))
def contrast(a, b):
    res = np.sum(np.equal(a, b))/(A.size)
    return res

res = contrast(A, B)
print("The correct rate is: %f"%res)

结果是:The correct rate is: 0.012400

如果我使用装饰器:

@gettime
def contrast(a, b):
    res = np.sum(np.equal(a, b))/len(a)
    return res

res = contrast(A, B)
print("The correct rate is: %f"%res)

会有报错:

contrast run time is: 0.00000 ms

TypeError: must be real number, not NoneType

当然,如果我删除print语句,我可以获得正确的运行时间,但res接受 Nonetype。

标签: pythondecoratornonetype

解决方案


由于包装器替换了被装饰的函数,因此它还需要传递返回值:

def wrapper(*args, **kw):
    t1 = time.time()
    ret = func(*args, **kw)  # save it here
    t2 = time.time()
    t = (t2-t1)*1000
    print("%s run time is: %.5f ms"%(func.__name__, t))
    return ret  # return it here

推荐阅读