What is Closures ?
—date:2019-09-19 originally posted here
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 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 be 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 the above function will be called a Nested function, not a Closure because
- Inner function [add10] doesn't access the local variable of enclosing function incx. It used the value of X rather than using a reference.
- Inner function [add10] cannot be executed outside the scope of incx.
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 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
- add10 function is accessing the local variable of the incx function. Here a reference to the local variable of incx is maintained in the add10.
- add10 can even be executed outside the body/scope of incx function.
Closure in python is created by a function call, here every time incx is called a new instance of this function is created. So whenever you call incx 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