It is possible to nest many decorators.
@decorator_one
@decorator_two
@decorator_three
@decorator_four
def some_silly_function():
pass
How do we write a decorator class so that the order in which the decorators is applied is inconsequential?
Ideally, for this application, we could permute the order in which the decorators are applied, and end result would be the same.
@decorator_two
@decorator_one
@decorator_four
@decorator_three
def some_silly_function():
pass
We would like to have the property that b1, b2, b3, b4 are all True after executing the following code:
b1 = isinstance(some_silly_function, decorator_one)
b2 = isinstance(some_silly_function, decorator_two)
b3 = isinstance(some_silly_function, decorator_three)
b4 = isinstance(some_silly_function, decorator_four)
For example, how might we edit the following decorator to better support nesting with other decorators?
import functools
class print_calling_args:
def __new__(cls, kallable):
instance = super().__new__(cls)
instance = functools.update_wrapper(instance, kallable)
return instance
def __init__(self, kallable):
self._kallable = kallable
self._file = sys.stdout
def __getattr__(self, attrname:str):
return getattr(self._kallable, attrname)
def __call__(self, *args, **kwargs):
print("__init__(" + ", ".join(str(x) for x in [self, *args]) + ")", file=self._file)
return self._kallable(*args, **kwargs)
An example of the decorator in use is here:
@print_calling_args
def stringify(*args, **kwargs):
return list("".join(str(elem)) for elem in arg for arg in args)
result1 = stringify("TESTING...", 1.1, 2.2, 3.3)
result2 = stringify("marco", "polo")
This decorator does not do anything very interesting. I am looking for more of a design pattern regarding decorators.