Ошибка 'Float object is not callable' при попытке запуска кода из книги Learning Python
Ввожу код ниже полностью в интерпретаторе, цикл for в самом конце тестирует только функцию forLoop, а дальше выходит ошибка File "<stdin>", line 2, in bestoftotal TypeError: 'float object is not callable
Помогите определить, что здесь не так
import time
def total(reps, func, *pargs, **kargs):
repslist = list(range(reps))
start = time.perf_counter()
for i in repslist:
ret = func(*pargs, **kargs)
elapsed = time.perf_counter() - start
return (elapsed, ret)
def bestof(reps, func, *pargs, **kargs):
best = 2 ** 32
for i in range(reps):
start = time.perf_counter()
ret = func(*pargs, **kargs)
elapsed = time.perf_counter() - start
if elapsed < best: best = elapsed
return (best, ret)
def bestoftotal(reps1, reps2, func, *pargs, **kargs):
return bestof(reps1, total, reps2, func, *pargs, **kargs)
reps = 10000
repslist = list(range(reps))
def forLoop():
res = []
for x in repslist:
res.append(abs(x))
return res
def listComp():
return [abs(x) for x in repslist]
def mapCall():
return list(map(abs, repslist))
def genExpr():
return list(abs(x) for x in repslist)
def genFunc():
def gen():
for x in repslist:
yield abs(x)
return list(gen())
for test in (forLoop, listComp, mapCall, genExpr, genFunc):
(bestof, (total, result)) = bestoftotal(5, 1000, test)
print ('%-9s: %.5f => [%s...%s]' % (test.__name__, bestof, result[0], result[-1]))
Ответы (1 шт):
У вас типичная питоновая ошибка - разные штуки в вашем коде называются одинаково.
bestof и total у вас одновременно и название функций и название переменных, которым вы присваиваете результаты работы функции bestoftotal. После такого присвоения нормальный вызов этих функций уже невозможен - вместо ссылок на функции в этих переменных лежат некие числа и Python не понимает, как можно эти числа вызвать как функции.
Починить это всё можно так, например, добавив подчёркивание к названиям переменных, совпадающих с названиями функций:
for test in (forLoop, listComp, mapCall, genExpr, genFunc):
(bestof_, (total_, result)) = bestoftotal(5, 1000, test)
print ('%-9s: %.5f => [%s...%s]' % (test.__name__, bestof_, result[0], result[-1]))
При этом переменная total_ у вас нигде не используется почему-то, но в целом код уже работает после такого изменения.