I would like to extend a library's decorator. I know that I can just call both decorators:
@my_decorator
@lib_decorator
def func():
pass
But I would like to avoid having to pass @lib_decorator
to each function each time. I would like my decorator to automatically decorate func()
with lib_decorator
. How can I do this? Can they be nested?
Simply write the decorator name using the “@” symbol before the function definition as shown below. In the following script, the functionality of the my_func() function is extended using the my_decorator() function. Finally, you can also extend multiple functions using a single decorator.
The call() decorator is used in place of the helper functions. In python, or in any other languages, we use helper functions for three major motives: To identify the purpose of the method. The helper function is removed as soon as its job is completed.
By definition, a decorator is a function that takes another function and extends the behavior of the latter function without explicitly modifying it. This sounds confusing, but it's really not, especially after you've seen a few examples of how decorators work. You can find all the examples from this article here.
You can incorporate the lib's decorator within yours. For simple, argument-less decorators, it's rather straight-forward:
def my_decorator():
@lib_decorator # <--- Just include the lib's decorator here
def inner:
func(*args, **kwargs)
return inner
It's a bit trickier for decorators that have arguments. Just remember that your decorator is replacing the decorated function with the inner-most function. So that's the one you need to decorate. So if you call your decorator with args, e.g.
@my_decorator(arg)
def func():
pass
Then decorate the inner function with the lib decorator:
def my_decorator(arg):
def wrapper(func):
@lib_decorator # <--- Just include the lib's decorator here
def inner(*args, **kwargs):
func(*args, **kwargs)
return inner
return wrapper
Or, using the class
form of the decorator function:
class my_decorator():
def __init__(self, arg):
pass
def __call__(self, func):
@lib_decorator # <--- Just include the lib's decorator here
def inner(*args, **kwargs):
func(*args, **kwargs)
return inner
You can easily transform a decoration like yours:
@my_decorator
@lib_decorator
def func():
pass
To this simpler decoration, using function composition:
my_composed_decorator = lambda func: my_decorator(lib_decorator(func))
@my_composed_decorator
def func():
pass
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With