A Detailed Guide of Closure in Python
|In this Python article, we will learn about closure, how to define them, and their importance. The closure is an important topic and may be asked in python interview questions. Let’s begin.
1. Nested Function and Nested Variables in Python
When we define any function inside another function in python, it is known as a nested function. Variables inside the enclosing scope can be accessed by the nested functions.
Python allows such nonlocal variables to access only to their scope limitations and not outside their respective scope. By default these variables are read-only and we should explicitly use the nonlocal keyword if we want to modify them.
Let’s implement an example to see how nested functions can access the variables of its enclosing scope.
def func_out(message): msg = message def func_in(): print(msg) func_in() func_out('Welcome to coding world')
Output Welcome to coding world
We can see that the function func_in()
can only be accessed inside the function func_out
body. Therefore, it can be said that func_in()
is a nested function that treats msg as a non-local variable.
Now, as we are clear with nested function and nested variable, let’s move closer to closure in python.
2. What is Closure in Python?
A closure is a nested function which has access to a free variable from an enclosing function that has finished its execution
We define closure as an object of function that remembers all the values present in enclosing scopes even if values are absent from the memory.
In simple words, closure is a log or a record that serves the purpose of storing functions together with an environment.
Closures are regarded as a mapping that associates every variable inside a function that is free(variables in an enclosing scope) with a certain value or a reference to the name it was bounded while creating the closure.
Briefly, a closure is an object that recalls its developing environment (enclosing scope).
def func_out(message): msg = message def func_in(): print(msg) return func_in callable = func_out('Welcome to coding world') callable() callable()
Output Welcome to coding world Welcome to coding world
In the example above, we do not call the function directly rather we return the function, and then we can all it again and again. It is clear that it remembers the value of its enclosing function.
Closure helps to call the functions outside their respective scope. With the help of closure, the scope can be easily extended.
import logging logging.basicConfig(filename='test.log', level=logging.INFO) def logger(sys_value): def check_log(*args): logging.info('Running "{}" with values {}'.format( sys_value.__name__, args)) print(sys_value(*args)) # Necessary for closure # returning WITHOUT parenthesis return check_log def new(val1, val2): return val1+val2 def remove(val1, val2): return val1-val2 new_log = logger(new) remove_log = logger(remove) new_log(2, 7) new_log(8, 4) new_log(11, 7) remove_log(15, 2) remove_log(32, 11) remove_log(21, 2)
Output 9 12 18 13 21 19
The above program will also create a test.log file that will tell the info for each of the six operations performed.
#inside the test.log file INFO:root:Running "new" with values (2, 7) INFO:root:Running "new" with values (8, 4) INFO:root:Running "new" with values (11, 7) INFO:root:Running "remove" with values (15, 2) INFO:root:Running "remove" with values (32, 11) INFO:root:Running "remove" with values (21, 2)
3. When and Why to use closure in python?
By studying the above example, we can conclude that we can use closure whenever in an enclosing scope a nested function references a value.
Let’s understand when and why to use closure in any program.
3.1. When to use Closure?
Some points to remember which should be met before creating closure in Python:
- There must be a nested function.
- The nested function must refer to a value that is defined in the enclosing function.
- The enclosing function must return a nested function.
3.2. Why to use Closure?
The closure is clearly used as a callback function, hence it provides some level of data hiding. which indirectly leads to a reduction in the use of global variables.
It is always better or even effective to use closure if there are only a few functions. For too many functions, it is preferred to use class. Given below is an example that shows that choosing closure will be better than choosing class and object.
Python Decorators also utilize closures extensively.
def divide_manytimes(divisor): def divide(value): return value / divisor return divide div_by_2 = divide_manytimes(2) div_by_4 = divide_manytimes(4) print(div_by_2(16)) print(div_by_4(48)) print(div_by_4(div_by_2(16)))
Output 8.0 12.0 2.0
In the above program, the div_by_2
and div_by_4
are closure values.
- First, 16 is divided by 2
- then 48 is divided by 4
- Lastly when div_by_2(16) is called inside div_by_4() which means ((16 / 2) / 4) which is equal to 2.
4. Conclusion
Finally, if we sum up, in this article we learned about closures along with some exampls. We have covered:
- Explain Nested function and Nested variables in python
- What is closure in python and what is the role of closure in python?
- When and why to use closure in python with examples
Helpful Links
Please follow the Python tutorial series or the menu in the sidebar for the complete tutorial series.
Also for examples in Python and practice please refer to Python Examples.
Complete code samples are present on Github project.
Recommended Books
An investment in knowledge always pays the best interest. I hope you like the tutorial. Do come back for more because learning paves way for a better understanding
Do not forget to share and Subscribe.
Happy coding!! ?