Python/Decorators
From charlesreid1
Advanced decorator usage: https://www.codementor.io/sheena/advanced-use-python-decorators-class-function-du107nxsv
Pretty mind-blowing use of a CLASS decorator, which takes one type of class in and returns another type of class out, and wraps the original class with a new one. This uses some advanced features of python classes as well to provide a transparent object wrapper.
In this case, when the user accesses attributes of the wrapper class, it first tries to return that attribute from the wrapper class; if that fails, it tries to return that attribute from the wrapped object. If the attribute is a function, it wraps that function handle with a decorator.
In effect, this wraps every single method implemented in the wrapped object, and decorates it with a timing method - which saves the user from having to copypaste a bunch of decorators (or worse, copypasta a bunch of code!).
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" oF = Foo() oF.a()