3

过去,我在同一个文件中编写了包含所有函数的 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'sprofile之类的东西profile.runctx('self.baz()', globals(), locals())。在处理许多类和方法时,这不是一个实用的解决方案。

4

2 回答 2

2

看看雅皮

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

import yappi
[...]
yapp.start()
some_function_that_needs_profiling()
yappi.print_stats()
于 2012-07-06T09:04:34.290 回答
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 或更高版本,您还可以创建一个类装饰器并将该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包装器应用于直接方法,而不是从基类继承的任何方法。

于 2012-07-06T09:14:52.080 回答