def make_multiplier(factor):
"""
code
"""
double = make_multiplier(2)
triple = make_multiplier(3)
print(double(5)) # Output: 10
print(triple(5)) # Output: 15
First try to get some idea about what has happen here yourself. Don’t worry about what is happening inside thhe make_multiplier function and you just need to find what would be the return. Take few minutes or longer as you like before read this further.
Okay. Lets check it. ‘make_multiplier’ function has been called twice with different arguments and the result has been saved in ‘double’ and ‘triple’ variables separately. So we just know ‘make_multiplier’ function has returned something at the end of the function.
In two print statements we can notice that these ‘double’ and ‘triple’ variables has been called as functions. Now we can identify that ‘make_multiplier’ function is also returned another function. Lets update the above code with new facts. Do it yourself before going further.
def make_multiplier(factor):
def multiply(x):
"""
code
"""
return multiply
double = make_multiplier(2)
triple = make_multiplier(3)
print(double(5)) # Output: 10
print(triple(5)) # Output: 15
I think I don’t need to explain above code. We just set the ‘multiply’ function inside ‘make_multiplier’ function. We can call ‘make_multiplier’ function is the outer function and ‘multiply’ is the inner function. We can also define the ‘multiply’ function as the nested function. I mean nested function is same as inner function. In the same we can the the outer function as the enclosing function.
Then lets go further. When we consider print statements, we can find that ‘double’ function multiply the given arguments by 2 and ‘triple’ function multiply the argument by 3. So where this should be happened? It should be happen in ‘multiply’ function. Again update the code. Try it yourself.
def make_multiplier(factor):
def multiply(x):
return factor*x
return multiply
double = make_multiplier(2)
triple = make_multiplier(3)
print(double(5)) # Output: 10
print(triple(5)) # Output: 15
If you couldn’t do it then at least try to understand above code yourself. For the calculation happen in ‘multiply’ function, it need two variables. Surely one variable is entered with double/triple function for the ‘multiply’ function. Then where is the other one? It is passed with ‘make_multiplier’ function. Another things. We have no problem regarding passing arguments to ‘multiply’ function. But we feel something wrong when we using ‘factor’, the argument of the outer/enclosing function inside ‘multiply’ function. Why we feel like that? You see we call ‘make_multiplier’ the outer function before we call ‘multiply’ function(inner function). Because of that ‘make_multiplier’ function is already returned, ended and it is finished. Normally after we call a function, we can’t access it’s variables(function scope) because they get destroyed after the function is finished. But here we access ‘factor’ even after it get destroyed. How we did that? We used it in the inner function and we returned the inner function. So its like inner function remembers the ‘factor’ before it get destroyed. This is called as a closure. Closure means, a nested function which can access and remember the values of outer/enclosing function after the outer/enclosing function returned/finished/get destroyed.
Here is the summary
- a function can return another function
- outer function = enclosing function
- inner function = nested function
- when the inner function accessing outer function’s variable even after completing(returning) the outer function, then we call it a ‘closure’.