2016-05-13 6 views
0

Ich habe eine Klasse namens Operatoren, und diese Klasse hat ein Bad von Funktionen. Ich möchte die ausgeführte Zeit für jede Funktion testen. Der Code sieht also wie folgt aus.So dekorieren Anweisung

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() 

Zunächst einmal verwenden self.Evaluate nicht funktioniert, außer ich Dekorateur nur finden verwendet für die Klasse und Funktion, also was soll ich tun? Danke vielmals.

Antwort

0

Wenn Sie Dekoratoren in einer Klasse für eine (oder mehrere) der Elementmethoden verwenden möchten, halte ich das nicht für sinnvoll. Als class ist ein aufgeräumter Container.

Verwenden Sie Dekorator für eine Funktion, und können Sie dann auf Modulebene Methoden oder Klassenmethoden verwendet werden.

Beispiel: Mit @timeit decorator können Sie die Ausführungszeiten dedizierter Methoden messen, indem Sie vor dem Methodenaufruf den @timeit-Dekorator hinzufügen.

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

cool, aber die Methoden, die ich alle messen möchte, sind Schnittstellen, ich kann Dekorator auf ihnen nicht hinzufügen. Was ich tun kann, ist nur in EvaluateWrap-Klasse. – bingo

+0

Es ist einfach, Anweisungen in Funktionen umzuwandeln. In Ihrem Fall können Sie 'def _run_A (self): self.op.A()' und def_run_B (self): self.op.B() 'definieren und sie von' Run' aufrufen. Wenn Ihr Decorator einen Status benötigt (z. B. weil Sie Zeit über viele Aufrufe hinweg sammeln), erstellen Sie eine separate 'Timer'-Klasse mit' timeit' als Aufrufmethode, die 'def __call __ (self, method) verwendet: ...'. Sie können sogar Zeiten pro Objekt für jede Methode verfolgen, indem Sie für jedes obj innerhalb der "zeitgesteuerten" Funktion "def timeed (obj, * args, ** kw)" akkumulierende Zeiten verwenden. – Neapolitan

Verwandte Themen