Может ли возвращаемое значение функции, измененной в python decorator, быть только Nonetype - PullRequest
0 голосов
/ 07 сентября 2018

Я написал декоратор, который получает время выполнения программы, но возвращаемое значение функции становится 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 принимает Нетип.

Ответы [ 2 ]

0 голосов
/ 07 сентября 2018

Или вы можете сделать:

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))
        print("The correct rate is: %f"%func(*args,**kw))
    return wrapper


@gettime
def contrast(a, b):
    res = np.sum(np.equal(a, b))/a.size
    return res
contrast(A,B)
0 голосов
/ 07 сентября 2018

Так как обертка заменяет декорированную функцию, ей также необходимо передать возвращаемое значение:

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