TLDR
How many functions can I wrap the actual decorator under? By actual decorator I mean the function that accepts the target function the as argument.
When passing arguments to a decorator in Python we do something like the following:
def decorator_maker_with_arguments(decorator_arg1, decorator_arg2):
print("I make decorators! And I accept arguments: {0}, {1}".format(decorator_arg1, decorator_arg2))
def my_decorator(func):
# The ability to pass arguments here is a gift from closures.
# If you are not comfortable with closures, you can assume it’s ok,
# or read: https://stackoverflow.com/questions/13857/can-you-explain-closures-as-they-relate-to-python
print("I am the decorator. Somehow you passed me arguments: {0}, {1}".format(decorator_arg1, decorator_arg2))
# Don't confuse decorator arguments and function arguments!
def wrapped(function_arg1, function_arg2) :
print("I am the wrapper around the decorated function.\n"
"I can access all the variables\n"
"\t- from the decorator: {0} {1}\n"
"\t- from the function call: {2} {3}\n"
"Then I can pass them to the decorated function"
.format(decorator_arg1, decorator_arg2,
function_arg1, function_arg2))
return func(function_arg1, function_arg2)
return wrapped
return my_decorator
This code is taken from this answer.
Notice that there is a wrapper around the actual decorator that handles the arguments that are given to the actual decorator.
The weird part is that you can decorate the target function with wrapper rather than use the decorator like so:
@decorator_maker_with_arguments("Leonard", "Sheldon")
def decorated_function_with_arguments(function_arg1, function_arg2):
print("I am the decorated function and only knows about my arguments: {0}"
" {1}".format(function_arg1, function_arg2))
decorated_function_with_arguments("Rajesh", "Howard")
#outputs:
#I make decorators! And I accept arguments: Leonard Sheldon
#I am the decorator. Somehow you passed me arguments: Leonard Sheldon
#I am the wrapper around the decorated function.
#I can access all the variables
# - from the decorator: Leonard Sheldon
# - from the function call: Rajesh Howard
#Then I can pass them to the decorated function
#I am the decorated function and only knows about my arguments: Rajesh Howard
So my question is that how many functions can I wrap around the actual decorator?
Take the code below as an example:
def level0(foo):
print("Level 0")
def level1(foo):
print("Level 1")
def level2(foo):
print("Level 2")
def dec(some_func):
print("Level 3")
def wrap():
print("Foo is " + foo)
some_func()
print("Level 3 End")
return wrap
return dec
return level2
return level1
@level0("foo")
def test():
print("From python")
Calling test
prints
Level 0
Level 1
TypeError: level2() missing 1 required positional argument: 'foo'
So is there a depth limit of just 2? Or am I doing something wrong?
Let me know if any other details from my side is required.