how can I profile class methods of my python app?

落爺英雄遲暮 提交于 2019-12-23 21:31:46

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!