2016-05-13 6 views
0

私はOperatorsという名前のクラスを持っていますが、このクラスには機能のバースがあります。各機能の実行時間をテストしたい。コードは以下のようになります。ステートメントの装飾方法

Class Operators(object): 
    def A(self): 
     """do something""" 
    def B(self): 
     """do something""" 

Class EvaluateWrap(object): 
    def __init__(self): 
     self.op = Operator() 
    def Evaluate(self): 
     def _Decorator(f): 
      functool.wrap(f) 
      def Wrap(*args, **kwargs): 
       # time_start 
       f(*args, **kwargs) 
       # time end, elapsed 
      return Wrap 
     return _Decorator 

    def Run(self): 
     @self.Evaluate() 
     op.A() 
     @self.Evaluate() 
     op.B() 

私はデコレータが唯一のクラスと機能のために使用していますので、私は何をすべき見つける以外にもまず第一に、self.Evaluateは動作しないでしょうか?どうもありがとう。

答えて

0

メンバーメソッドの1つ(またはそれ以上)のクラス内でデコレータを使用したい場合、私はそれが妥当ではないと思います。 classはきれいな容器です。

は、デコレータを1つの関数で使用し、モジュールレベルのメソッドまたはクラスメソッドに使用できます。

たとえば、 @timeit decoratorを使用すると、メソッド呼び出しの前に@timeitデコレータを追加するだけで、専用メソッドの実行時間を測定できます。

import time 

def timeit(method): 

    def timed(*args, **kw): 
     ts = time.time() 
     result = method(*args, **kw) 
     te = time.time() 

     print '%r (%r, %r) %2.2f sec' % \ 
       (method.__name__, args, kw, te-ts) 
     return result 

    return timed 

class Foo(object): 

    @timeit 
    def foo(self, a=2, b=3): 
     time.sleep(0.2) 

@timeit 
def f1(): 
    time.sleep(1) 
    print 'f1' 



f1() 
Foo().foo() 

output: 
f1 
'f1' ((), {}) 1.01 sec 
'foo' ((<__main__.Foo object at 0x103b849d0>,), {}) 0.20 sec 
+0

クールですが、私がすべて測定したいメソッドはインターフェースなので、デコレータを追加することはできません。私ができることはEvaluateWrapクラスだけです。 – bingo

+0

ステートメントを関数に変換するのは簡単です。あなたの場合、 'def _run_A(self):self.op.A()'とdef_run_B(self):self.op.B() 'を定義し、それらを' Run'から呼び出すことができます。デコレータが状態を必要とする場合(例えば、多くの呼び出しで時間が累積しているなど)、 'def __call __(self、method):...'を使用して 'timeit'を呼び出しメソッドとして別の' Timer'クラスを作成します。 'timed'関数内でobjごとに' def timed(obj、* args、** kw) 'の積算時間を使って各メソッドのオブジェクトごとの時間を追跡することさえできます。 – Neapolitan

関連する問題