There are a few pre-requisites before understanding how closures work in python and their significance. It is important to understand what a nested function is, and, what the non-local variable is before proceeding ahead with python closures. We have already covered the topic non-local variables in python and we recommend you to go through it.
Note: We will use the word function and method interchangeably, so do not get confused.
A nested function is nothing but a function that is housed/defined within another function. The nested functions have the ability to access all the variables within its enclosing scope only.
The rule for non-local variables is that they can be accessed within their own scope and nowhere else.
Example to demonstrate the implementation of nested method:
def function_outside(data):
data = data
# function inside a function
def function_inside():
print(data)
# calling the inside function
function_inside()
if __name__ == '__main__':
function_outside("Hi Studytonight")
Output:
Hi Studytonight
As mentioned previously, it can be observed that the method function_inside
could easily access the function_outside
. But this function_inside
can't be accessed outside the body of the function_outside
. This demonstrates nested methods. Here, the argument passed to the function_outside
is a non-local value. This value could be easily accessed and used by function_inside
.
Example to demonstrates the use of the non-local keyword
def print_contents(data):
def print_me():
nonlocal data
data = "This is a sample"
print(data)
print_me()
print(data)
print_contents("Studytonight")
Output:
This is a sample
This is a sample
The data
variable is a non-local value, hence the nested method as well as the outer method, both of them resulted in printing the same value. Had there been no non-local keyword, the output would have been :
This is a sample
Studytonight
What are Python Closures?
Closures in python are function objects which have the ability to remember some amount of data (present in the enclosing scope) even after the execution of code is complete. It stores a function and its environment by mapping every variable present within the function to a reference (or value) to which it is bound during the creation of a closure. The cool aspect of closure is that it allows the function data to be seen even after its execution is over.
Time for an example:
def data_transfer(message): # outer method
def data_transmission(): # nested method
print(message)
return data_transmission
nested_fun = data_transfer("This is calling the nested method")
nested_fun()
Output:
This is calling the nested method
Note: In Python, decorators use closures heavily.
Why use Python closures at all?
-
During the usage of callback functions, the usage of closures helps in data hiding as well as in the reduction of usage of global variables.
-
When the number of methods that need to be implemented inside a class is few in number, closures can be used instead, since they tend to provide a much elegant solution.
-
In case the number of methods that need to be implemented is more, it is strongly suggested to take advantage of object-oriented concepts and programming design.
Conclusion
In this post, we understood about closures, their significance and how and in what situations they could potentially be used.