I have made two functions doing the same thing but differently. I want to compare the time each function takes to run so I have added a decorator @calcul_time. The script does work but i get the following error message:
{1: 1, 2: 3, 3: 2, 4: 4, 5: 4, 6: 3, 7: 3, 8: 2, 9: 2, 10: 2, 11: 2, 12: 2, 13: 2, 14: 2, 15: 2, 16: 2, 17: 2, 18: 2, 19: 2, 20: 2, 21: 2, 22: 2, 23: 0, 24: 0}
0.0021219253540039062
{1: 1, 2: 3, 3: 2, 4: 4, 5: 4, 6: 3, 7: 3, 8: 2, 9: 2, 10: 2, 11: 2, 12: 2, 13: 2, 14: 2, 15: 2, 16: 2, 17: 2, 18: 2, 19: 2, 20: 2, 21: 2, 22: 2, 23: 0, 24: 0}
8.702278137207031e-05
Traceback (most recent call last):
File "./03_PeakHours.py", line 51, in <module>
horaires1()
TypeError: 'NoneType' object is not callable
I don't understand why I have this NoneType error message. If I comment my decorator, I don't have any errors. Hereunder my script. Does anyone know why I get this 'NoneType' error?
#!/usr/local/bin/python3.5
import time
input='''5
1 8
2 3
4 23
4 6
2 23'''
def calcul_time(fonction):
avant = time.time()
fonction()
apres = time.time()
print(apres - avant)
#@calcul_time
def horaires1():
hours = {}
for time in range(1,25):
hours[time] = 0
def inBetween(line):
current = int(line.split(" ")[0])
while current < int(line.split(" ")[1]):
hours[current] +=1
current += 1
list(map(inBetween, input.split("\n")[1:]))
print(hours)
return 0
#@calcul_time
def horaires2():
lines = input.split("\n")
hours={}
for time in range(1,25):
hours[time] = 0
for i in range(1, int(lines[0])+1):
start, stop = lines[i].split(" ")
for heure in range(int(start), int(stop)):
hours[heure] += 1
print(hours)
return 0
horaires1()
horaires2()
You haven't really built a decorator. A decorator has to return a the original function or a suitable replacement.
Your decorator returns nothing:
A decorator typically returns a wrapper function. You created the wrapper function, but not the decorator that returns it.
This would be a proper decorator:
I renamed your
calcul_time
wrapper towrapper
, removed thefonction
argument (that would be passed to the decorator, you can rely on it as a closure), and returned thewrapper
. Now the decorator returns a replacement.You probably want to make it a little more generic, and pass through arbitrary arguments with
*args
and**kwargs
, and handle both the return value (pass it through to the caller ofwrapper()
) and exceptions correctly.You also want to use the
@functools.wraps()
decorator to copy things like the name and attributes from the wrapped function to the wrapper:The
try..finally
ensures thatprint()
is executed regardless of what happens infonction
.