2016-05-13 53 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

如果你想在一个(或多个)成员方法的类中使用装饰器,我不认为这是合理的。作为class是一个整洁的容器。

在一个函数上使用装饰器,然后可以使用模块级方法或类方法。

例如, @timeit装饰器允许您通过在方法调用前添加@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