I want to count how many times each function get called. I have a wrapper to do the counting and save it into a global variable
def counter(f):
global function_calls
function_calls = 0
def wrapper(*args, **kwargs):
global function_calls
function_calls = 1
return f(*args, **kwargs)
return wrapper
and then other two functions to be decorated for counting
@counter
def square(x):
return x * x
@counter
def addition_by_self(x):
return x x
Now when I call the function five time each the global variable function_calls
returns 10. Which makes sense.
print(square(x=4))
print(square(x=4))
print(square(x=4))
print(square(x=4))
print(square(x=4))
print(addition_by_self(x=4))
print(addition_by_self(x=4))
print(addition_by_self(x=4))
print(addition_by_self(x=4))
print(addition_by_self(x=4))
print(f"Number of the function got called: {function_calls}")
running the file gives the output.
16
16
16
16
16
8
8
8
8
8
Number of the function got called: 10
Now I need some solutions or ideas on how to make the decorator return how many times each function got called, not an aggregation of all the calls. I might have other functions which I need track the number of times they also got called.
Essentially I want to do something like print(function_calls) # or something proper
and get the out like: sqaure got called 5 times and addition_by_self got called 5 times
CodePudding user response:
Instead of a single global int
, store per-function counts in a dict
.
def counter(f):
global function_calls
function_calls = {}
def wrapper(*args, **kwargs):
global function_calls
function_calls[f.__name__] = 1
return f(*args, **kwargs)
return wrapper
f
might make a better key than f.__name__
(multiple distinct functions could have the same name), but this works as a simple example.
CodePudding user response:
Using a list and an attribute:
def counter(f):
global funs
try:
len(funs)
except NameError:
funs = []
funs.append(f)
f.function_calls = 0
def wrapper(*args, **kwargs):
f.function_calls = 1
return f(*args, **kwargs)
return wrapper
@counter
def square(x):
return x * x
@counter
def addition_by_self(x):
return x x
for i in range(10):
print(square(3))
print(addition_by_self(2))
print(addition_by_self(4))
for f in funs:
print(f'function: {f.__name__}, calls: {f.function_calls}')