Reputation: 103
I just discovered that decorator is one way of nesting functions and I came across this peculiar case with a concept called "closure". It basically means the nested function has access to the outter scope of an enclosing function. This looks intuitive enough till I found this piece of code as follows,
def decorator_with_arguments(function):
"this decorator actually takes a real function as input"
def wrapper_accepting_arguments(arg1,arg2):
print("My arguments are: {0},{1}".format(arg1,arg2))
function(arg1,arg2)
return wrapper_accepting_arguments
@decorator_with_arguments
def cities(city_one,city_two):
print("Cities I love are {0} and {1}".format(city_one,city_two))
cities("Beijing","Chicago")
The output would be as follows,
My arguments are: Bejing,Chicago
Cities I love are Bejing and Chicago
I have two questions regarding this piece of code.
First of all, isn't it amazing that the function wrapper_accepting_arguments
understands that the arg1 and arg2 come from the function and print them off in a certain way before it has access to the function(arg1,arg2)
? Does Python interpreter not read line by line? I understand when you apply multiple decorators to a function, say you have two @ along with a function, then the @ at the bottom gets excuted first. But within the body of a function, why it is read backwards?
The second question is that, if you delete the line of function(arg1,arg2)
(as I tried to understand what it does), the output would be as follows,
My arguments are: Beijing,Chicago
as if you had never called the function of "cities" defined at the bottom. why is that?
This along with recursion works in a miraculous way. It's certainly not linear or from top down.
Thank you very much! Any pointer would be really appreciated!
Upvotes: 0
Views: 55
Reputation: 1965
The moment this code
@decorator_with_arguments
def cities(city_one,city_two):
print("Cities I love are {0} and {1}".format(city_one,city_two))
gets imported, the function decorator_with_arguments
is called with the function cities
as parameter. This will immediately return your inner function wrapper_accepting_arguments
, which will effectively replace the definition of def cities
.
So when you then call cities("Beijing","Chicago")
, it is actually calling that inner function wrapper_accepting_arguments
with the arguments "Beijing","Chicago"
. This will cause My arguments are: Beijing,Chicago
to be outputted followed by a call to the original definition of the cities
(which was saved in the closure) resulting in Cities I love are Beijing and Chicago
being printed.
Upvotes: 1