过去我编写了包含所有函数的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())
之类的内容。在处理许多类和方法时,这不是一个实用的解决方案。
答案 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
包装器应用于直接方法,而不是从基类继承的任何方法。