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の前にデコレータを追加しましたが、実行すると、結果のファイルは空になりますmyAppkernprof.py.prof

では、クラスのメソッドをプロファイリングする最も簡単な方法は何ですか?デコレータとフラグを使ってこれをオン/オフに切り替えたいと思います。

編集1:私はここで可能な最も簡単な解決策に本当に興味があります。デコレータはエレガントなソリューションであることがわかりますが、もっと簡単にできるかもしれません。私がやりたくないのは、cProfile'sプロファイルのようなものを使用することです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 に答える