Python decorators
I have a project at work where in Python, where I use decorators to wrap functionality for views. I hit on a snag when I used 2 decorators on 1 function. I like using class decorators, I read some recommendations regarding that, and it fits better with my Java upbringing
. The 2 decorators I needed to apply to the same function looked like this (__call__ method omitted for brevity):
1 2 3 4 5 6 7 8 9 | class AutoTemplate(object): def __init__(self, func): self.func = func pathElems = func.__module__.split(".")[:-1]+["%s.html"%func.__name__] self.template = os.path.join(* pathElems) class AccessRequired(object): def __init__(self, func): self.func = func |
In addition, I used the functions actual name in the urls.py file to generate the url tuple:
1 2 3 | def createUrl(method): name = method.func.func_name return (r'^%s.html$'%name, method, {}, name) |
So the finished product after decorators where applied needed to work for that. Because the decorators resulted in a class rather than a function being assigned to the the view, this didn’t work properly.
With a little help from Stackoverflow however, I came upon a good solution, that makes it really transparent that a function is actually decorated:
1 2 3 4 5 6 7 8 | class DecoratorBase(object): def __init__(self, func): self.func = func for n in set(dir(func)) - set(dir(self)): setattr(self, n, getattr(func, n)) class AutoTemplate(DecoratorBase): pass class AccessRequired(DecoratorBase): pass |
This does not work for decorators requiring parameters, I will see if I can find a solution for that if I need it.