Python closures are used in nested functions, and python has a built-in implicit support for nested functions. A nested function is a function within a function that is defined implicitly and can access all the variables within the parent function, the nested function uses non-local variables which can only be accessed within own and parent scopes. A closure is best-defined as a function-object which can retain the value assigned from the enclosing scopes even if they are not present in the memory of the function.

Let’s see an example where we build a function within a function or a nested function:

def outerclosure(txt):#This is the parent scope or the main function

   def innerclosure(): #This is the child function better known as the nested function
       print(txt) #This command prints the text passed to the non-local string variable in the parent scope

   return innerclosure #This returns the innerclosure to the parent closure


#outerclosure("My Function") #This calls the outer closure which uses the nested callback function to print the string variable

clos1 = outerclosure("My Function") 

clos1() #This is a closure

We saw the use of closures, which are the function object utilising the non-local objects in the nested function, we can implement many functions with the use of closures, it provides the user with some aspect of abstraction and data-security. Closures are a good example of implementation of OOP principles and can be manipulated in many ways and multiple closures can also be implemented in a single nested function or multiple nested functions. 

Let’s see another example of how a closure works.

def plus1(n): #This is the parent function

   def plus2(x): #This is the nested child function
       return x + n #this value returns x+n from the nested function

   return plus2 #This returns the nested function to the parent function which can later be called upon


num1 = plus1(7) #Another variable "num1" stores the parent function with the main non-local variable call.

num2 = num1(14) #The second variable holds the first parent function with another value assigned to the function.

print(num2) #This prints the closure function obj.

If you look at the num1 object, you can see that it holds the parent function and the parent function returns the nested function to the main code while working on a non-local variable accessed from the parent function, the value assigned to plus1 is 7.

Take a look at num2, it contains num1() as a function, even though we replaced the initial value of the function plus1 with 14, it retains the original value of 7 and adds them both as we have defined two non-local variables in the parent and nested function. This entire operation or the function object num2 is called a closure.

An important part of making a closure is that it has some requirements that must be fulfilled by the code in order for the closure to work. To make a closure work, it must be implemented upon a nested function, a regular function will not work with closures, the nested child function must be accessing the non-local variable which is defined in the parent function, a value defined in the nested function will not work with closure. The parent function must return the nested function to the main code otherwise the closure will not work. 

Let’s see another example of a closure being implemented via a string object:

  def string2(): #This is the nested/child function, this accesses the non-local string variable defined in the parent function
       length = len(str1) #this obtains the length of the string
       for i in range(0, length): #A simple for loop to print the characters in a string one by one
           print(str1[i])

   return string2 #The main function returns the nested/child function which is then called using a closure


close1 = string1("My Closure") #Making a closure, a function object is created which contains the parent function with the string var.

close1() #Calling the closure.

In the above code, we made a simple character counting code using closures and nested functions, the close1() function object is a closure which contains the parent function call with the string defined as the non-local variable.

Categorized in: