I have a a collection of functions inside a file myfile.py and I would like to add a timer print automatically for each of them: (have around 700 functions)
def myfunXXX()
mytime.start()
mytime.end()
mytime.start(): to= time.time()
mytime.end(): print(time.time() - t0)
Current solutions are :
- Add a decorator manually to all the functions.
- Add the code snippet to all the functions
Is there a way to "hack" Python and the function base definition to add those 2 functions before executing and at execution end for a set of Python functions ?
Maybe using AST and injecting some string code ?
CodePudding user response:
sys.setprofile is meant exactly for this.
Make sure you filter according to frame.f_code.co_filename
to only stop on the wanted files.
On call event start the timer, on return stop.
Make sure you use time.perf_counter
as the timer. The others are less reliable.
Keep in mind, as any other profiler that checks all functions in a module, especially one written in Python, it will slow down your code.
CodePudding user response:
One solution if you're willing to modify where you call these functions is to do something like this:
import time
def wrapper(function,args):
start = time.time()
function(args)
end = time.time()
print(end-start)
I know you don't want to add decorators because you have a lot of functions to add them to. If you're willing to put your functions in a class you might find this answer or this answer useful on automatically adding decorators to classes.
CodePudding user response:
Decorators that Patch Classes is one "hack" that comes to mind.
def _task(cls):
og_attrs = cls.__getattribute__
def new_getattrs(self, name):
return og_attrs(self, name)
cls.__getattribute__ = new_getattrs
return cls
@_task # mass change in class method's behavior
class A:
def reborn_function(self):
pass
Your whole issue might not go away at once. But this is the closest thing you have to be backward compatible and elegant. Ast will be a wrong move if you are worried about API changes or backward compatibility.