Quick actions

cmd+k|ctrl+k

Navigation

Languages

Python Decorators: timer with a Class decorator

Snippet info

Language

Python

Visibility

public

Author

atymo

Created

2018-05-13T13:23:42Z

Updated

2018-05-13T21:29:04Z

def time_this(original_function):      
    print("decorating")                      
    def new_function(*args,**kwargs):
        print("starting timer")
        import datetime                 
        before = datetime.datetime.now()                     
        x = original_function(*args,**kwargs)                
        after = datetime.datetime.now()                      
        print("Elapsed Time = {0}".format(after-before))
        return x                                             
    return new_function  

def time_all_class_methods(Cls):
    class NewCls(object):
        def __init__(self,*args,**kwargs):
            self.oInstance = Cls(*args,**kwargs)
        def __getattribute__(self,s):
            """
            this is called whenever any attribute of a NewCls object is accessed. This function first tries to 
            get the attribute off NewCls. If it fails then it tries to fetch the attribute from self.oInstance (an
            instance of the decorated class). If it manages to fetch the attribute from self.oInstance, and 
            the attribute is an instance method then `time_this` is applied.
            """
            try:    
                x = super(NewCls,self).__getattribute__(s)
            except AttributeError:      
                pass
            else:
                return x
            x = self.oInstance.__getattribute__(s)
            if type(x) == type(self.__init__): # it is an instance method
                return time_this(x)                 # this is equivalent of just decorating the method with time_this
            else:
                return x
    return NewCls

#now lets make a dummy class to test it out on:

@time_all_class_methods
class Foo(object):
    def a(self):
        print("entering a")
        import time
        time.sleep(3)
        print("exiting a")
        
    def b(self):
        print("entering b")
        import time
        time.sleep(0.5)
        print("exiting b")
        
    def c(self):
        print("entering c")
        import time
        time.sleep(0.9)
        print("exiting c")

oF = Foo()
oF.a()
oF.b()
oF.c()
INFO