2012-02-14 8 views
2

Pythonで記述している既存のコードから各関数または変数の呼び出し時間を取得したい。呼び出される関数または変数の回数を計算する

acc = {} 

class object(object): 
    def __getattribute__(self, p): 
     acc.update({str(self) + p: acc.get(str(self) + p, 0) + 1}) 
     return supe(object, self).__getattribute__(p) 

class A(object): 
    def a(self): 
     pass 

class B(A): 
    def b(self): 
     pass 

def main(): 
    a = A() 
    a.a() 
    b = B() 
    b.b() 
    b.a = 'a' 
    b.a 

    print acc 
if __name__ == '__main__': 
    main() 

をしかし、それは唯一のオブジェクト内の関数や変数を計算することができ、私は通常の関数や変数を計算することができますどのように、など:私は考えて何

は、以下のように、オブジェクトののgetAttribute関数をオーバーライドしています次のようになります。

def fun1(): 
    pass 
fun1() 
fun1() 

結果を2にしたいのですが、ツールや方法はありますか?

申し訳ありませんが私のプールの英語、私が本当に必要なのは、実行時ではなく呼び出された時間です。上記のような 、私たちは言った、fun1()は2回呼び出されます。

+4

'クラスオブジェクト(オブジェクト)' - 本当に? –

+0

うん、私はそう思います、私の愚かな方法を忘れてください – flreey

+0

どのように変数呼び出しを数えますか? – Marii

答えて

2

decoratorを使用してください。

>>> def timestamp(container, get_timestamp): 
...  def timestamp_decorator(func): 
...   def decorated(*args, **kwargs): 
...    container[func.func_name] = get_timestamp() 
...    return func(*args, **kwargs) 
...   return decorated 
...  return timestamp_decorator 
... 

そして、あなたはこのようにそれを使用します。

>>> import datetime 
>>> def get_timestamp(): 
...  return datetime.datetime.now() 
... 
>>> timestamps = {} 
>>> @timestamp(timestamps, get_timestamp) 
... def foo(a): 
...  return a * 2 
... 
>>> x = foo(2) 
>>> print x, timestamps 
4 {'foo': datetime.datetime(2012, 2, 14, 9, 55, 15, 789893)} 
+0

コードはalredyで書かれています。私はすべての関数にデコレータを追加したくないのですが、変数についてはどうですか? – flreey

+0

@flreey、hmmm ...それについて考えるでしょう。 – senderle

+0

私は申し訳ありませんが、私の質問はあなたが本当に何回呼び出されたのか知りたいと思います。例えば、a = A();たのしい(); a.f()と私は、結果を取得したい。funは2回呼び出します。 – flreey

0

(タイムスタンプデコレータNBOT)関数にカウンターデコレータを作成する - と、自動的に与えられた中で、すべての機能をラップする方法があるでしょうこのデコレータを持つモジュール - そう

、あなたが機能をカウントするモジュールは、あなたが書くことができます「のmymodule」という名前で呼び出す場合:

class function_counter(object): 
    def __init__(self, func): 
     self.counter = 0 
     self.func = func 

    def __call__(self, *args, **kw): 
     self.counter += 1 
     return self.func(*args, **kw) 

そして:機能の使用状況をカウントするだろう

import mymodule 
from types import FunctionType, BuiltinFunctionType 
# define the "function_counter" class as above here (or import it) 

for key, value in mymodule.__dict__.items(): 
    if isinstance(value, (FunctionType, BuiltinFunctionType)): 
     mymodule.__dict__[key] = function_counter(value) 

:モジュール内のすべての関数にこれを適用するに

>>> @function_counter 
... def bla(): 
...  pass 
... 
>>> 
>>> bla() 
>>> bla() 
>>> bla() 
>>> bla.counter 
3 

、あなたのような何かを書くことができます。 モジュールレベルの変数の使用状況を数えたい場合は、それほど簡単ではありません。 のように、モジュールオブジェクトから取得するメカニズム属性をオーバーライドすることはできません。

ここに行く方法は、あなたのモジュールをインポートした後で、あなたの例のように属性計数スキームを実装するクラスのためにあなたのモジュールを置き換えて、すべてのモジュール属性をインスタンス属性に割り当てますこのクラス。

これは(上記とは違って)テストの例ではありませんが、一緒に何かをしてみてください:

import mymodule 

from types import FunctionType 

class Counter(object): 
    # counter __getattribute__ just as you did above 

c = Counter() 
for key, value in mymodule.__dict__.items(): 
    setattr(c, key, staticmethod(value) if isinstance(value, FunctionType) else value) 
mymodule = c 
+0

私はあなたのメソッドをテストし、私はmymoduleをインポートするときに定義された関数の数を取得します。実際に必要なのは、実行時に関数や変数の呼び出し回数をカウントできるようなものです。 – flreey

関連する問題