我怎样才能分析我的python应用程序的类方法?

时间:2012-07-06 08:53:04

标签: python profiler

过去我编写了包含所有函数的python代码在同一个文件中,我可以使用以下代码来编写程序:

这是我写的装饰者:

def do_profile(cond):
    def resdec(f):
        if not cond:
            return f
        return profile(f)
    return resdec

这就是我使用它的方式:

@do_profile(DO_PROFILE)
def my_func():
    return 1

然后我会在我的脚本上调用kernprof.py

kernprof.py  -l my_program.py

与此同时,我对OOP更加熟悉,并将程序重写为多个类,程序现在就像这样开始:

 if __name__ == "__main__":
     my_app = myApp()
     my_app.run()

myApp是一个与其他类进行大量沟通的类:

class myApp():
    @do_profile(DO_PROFILE)
    def foo_method(self, arg1):
        pass

我在每个do_profile方法前添加了myApp装饰器,但如果我运行kernprof.py,则生成的.prof文件为空

那么分析类方法的最简单方法是什么?我真的很想用装饰器和旗帜打开/关闭它。

EDIT1:我真的对这里最简单的解决方案感兴趣。找到装饰器是一个优雅的解决方案,但也许事情可以更轻松地完成。我不想做的是使用cProfile's个人资料profile.runctx('self.baz()', globals(), locals())之类的内容。在处理许多类和方法时,这不是一个实用的解决方案。

2 个答案:

答案 0 :(得分:2)

查看Yappi

要分析一段代码,只需使用:

import yappi
[...]
yapp.start()
some_function_that_needs_profiling()
yappi.print_stats()

答案 1 :(得分:1)

profile函数本身就是一个装饰器,和大多数装饰器一样,它们只需要应用于函数。

幸运的是,类方法基本上是在创建实例时绑定到实例的函数。因此,您可以通过方法本身将装饰器放入类定义中来将装饰器应用于任何类方法:

class myApp(object):
    @do_profile(DO_PROFILE)
    def foo_method(self, arg1):
        pass

    @do_profile(DO_PROFILE)
    def bar_method(self, arg2):
        pass

如果您使用python 2.6或更高版本,您还可以创建class decorator并将profile装饰器应用于任何给定类的所有方法。您可以通过将装饰器放在类定义之前来应用它:

@do_profile_all_methods(DO_PROFILE)
class myApp(object):
    def foo_method(self):
        pass

这样的装饰者看起来像这样:

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

此装饰器仅将profile包装器应用于直接方法,而不是从基类继承的任何方法。