问题
In the past I've written python code with all functions in the same file, and I could profile my programs using the following code:
This is a decorator I wrote:
def do_profile(cond):
def resdec(f):
if not cond:
return f
return profile(f)
return resdec
And this is how I use it:
@do_profile(DO_PROFILE)
def my_func():
return 1
I would then invoke kernprof.py
on my script:
kernprof.py -l my_program.py
In the meantime I got more familiar with OOP and I rewrote my program into many classes and the program is now started like this:
if __name__ == "__main__":
my_app = myApp()
my_app.run()
myApp
is a class which is also communicating heavily with other classes:
class myApp():
@do_profile(DO_PROFILE)
def foo_method(self, arg1):
pass
I've added the do_profile
decorator in front of each myApp
method, but if I run kernprof.py
, the resulting .prof
file is empty
So what's the easiest way of profiling a methods of a class? I would really love to switch this on / off with a decorator and a flag.
EDIT1: I'm really interested in the easiest possible solution here. A find a decorator to be an elegant solution, but maybe things can be done easier. What I DO NOT want to do, is using stuff like cProfile's
profile profile.runctx('self.baz()', globals(), locals())
. That is not a practical solution when handling many classes and methods.
回答1:
The profile
function is a decorator itself, and like most decorators, they need to be applied to functions only.
Luckily, class methods are basically functions that are bound to an instance when an instance is created. Thus, you can apply your decorator to any class method by putting it in the class definition by the methods themselves:
class myApp(object):
@do_profile(DO_PROFILE)
def foo_method(self, arg1):
pass
@do_profile(DO_PROFILE)
def bar_method(self, arg2):
pass
If you use python 2.6 or up, you can also create a class decorator and apply the profile
decorator to all methods on any given class. You'd apply it by placing the decorator right before the class definition:
@do_profile_all_methods(DO_PROFILE)
class myApp(object):
def foo_method(self):
pass
Such a decorator could look something like this:
import types
def do_profile_all_methods(cond):
if not cond:
return lambda c: c # Do nothing with the class; the 'null' decorator
def profile_all_methods(klass):
for name, attr in klass.__dict__.items():
if isinstance(attr, types.UnboundMethodType):
klass[name] = profile(attr)
return klass
return profile_all_methods
This decorator only applies the profile
wrapper to direct methods, not any inherited from the base class.
回答2:
Take a look at Yappi
To profile a piece of code simply use:
import yappi
[...]
yapp.start()
some_function_that_needs_profiling()
yappi.print_stats()
来源:https://stackoverflow.com/questions/11358963/how-can-i-profile-class-methods-of-my-python-app