Python decorator class to decorate standalone functions and object methods
The advanced technique that I describe below assumes you understand basic mechanic of Python decorators and Python descriptors.
Suppose we want to decorate method
func_to_wrap of the class
If we create Python decorator class as below:
We will fail to use it:
func_to_wrap() missing 1 required positional argument: 'self'
As we can see from the error
self. This is because
it’s not bound to object instance and we have to pass the instance as first argument.
But we cannot!
Decorator.__call__ is the instance of
We do not have
ClassToWrap instance inside
Of cause there is simple solution - write the decorator as function.
But I am goin to show you how to write decorator as class, using Python descriptors.
Moreover the decorator will be universal and could be applied to standalone functions as well as to object methods.
The Python descriptor protocol is very simple - if object attribute has method
then Python will call it and return as the attribute value the result of
Below you can see working example.
UniversalDecorator.__call__ will work if we decorate standalone functions.
For class method instead of
__call__ Python will call
__get__ and after that call the result of it as a function.
with links to both
When Python call the
__get__ result (instance of
WrapperHelper) it will actually call
WrapperHelper.__call__ add instance of
ClassToWrap, as first item in
func_to_wrap will get instance of
ClassToWrap as first argument.