Today we will talk about Closure a functional object in Python.
Closure is a function object which has access to the local variables/free variables of the enclosing scope and can be executed outside of its scope. Nested function is a Closure function if
- It can access variables that are local to enclosing scope.
- It can be executed outside for its scope.
Closure can used for one of these
- Replacing the hard coded constants.
- Eliminating global.
- Can be used for data hiding and many other things.
So lets see with a code snippet to see how closure and nested function are different from each other.
# nested functions
def inc_x(x):
def add_10(x=x):
print("{0} is increased by 10 = {1}".format(x, x+10))
return add_10() # remember about the parenthesis.
inc_value = inc_x(10)
inc_value #Output: 10 is increased by 10 = 20
So above function will be called a Nested function, not a Closure because
- Inner function [add_10] doesn’t access the local variable of enclosing function inc_x. It used the value of X rather than using a reference.
- Inner function [add_10] cannot be executed outside the scope of inc_x.
Now let see the Closure function example.
# closure functions
def inc_x(x):
def add_10():
print("{0} is increased by 10 = {1}".format(x, x+10))
return add_10 # returning function without parenthesis, passing only references.
inc_value = inc_x(10)
# We are able to execute the inner function outside of its scope.
inc_value()
#Output: 10 is increased by 10 = 20
So above code will be called as Closure function rather than Nested function because
- add_10 function is accessing the local variable of the inc_x function.Here a reference to the local variable of inc_x is maintained in the add_10.
- add_10 can even be executed outside the body/scope of inc_x function.
Closure in python is created by a function call, here every time inc_x is called a new instance of this function is created. So whenever you call inc_x a binding reference is made to x which is used in add_10 function.
So let see how under the hood these variable reference are maintained
- Function attributes func_closure in python < 3.X or closure in python > 3.X save the these references to these variable or also called as free variable. Let see how to access these values.
# Taking same example for the above code
def inc_x(x):
def add_10():
print("{0} is increased by 10 = {1}".format(x, x+10))
return add_10
add_10 = inc_x(30)
add_10()
# Output: 30 is increased by 10 = 40
# Checking whether it is Closure or not.
'__closure__' in dir(add_10)
# Output: True
# Getting the free variable value from closure.
add_10.__closure__[0].cell_contents
# Output: 30
While talking about the closure we also heard the term free variables which is also an interesting topic to discuss, which I will cover in the next blog post, till then
Cheers !! 🙂
Happy Learning