Python Closures Tutorial

A closure is a nested inner method or function that recognizes and has the privilege to use the variables even after the outer function has finished executing in the local scope in which it was created. A variable must be from an outer function or scope and is not certainly bounded in the local space to be used. There are three features of a Python closure, these are as follows:

  • It must be a nested method/function.
  • It must have accessibility to a free variable in outer space.
  • It must revert from the outer function.

Nested Function

You first have to grasp what a nested method is. A nested function can be defined as a method specified within another method. Recursive functions may reach the outer scope’s variables. To change the non-local variables, we specifically define them as non-local via nonlocal keywords because they are by nature read-only. So, first, have a look at the nested function performed in Spyder Python 3.

We have defined two functions: the outer and the inner. In the outer function, we have declared a variable with some text value in it.

def outer_func()
msg = ‘Hy! I am Aqsa Yasin’

This variable has been printed in the inner function using a print statement. The inner function is then returned, which is a nested function, and after that, the outer function has been called.

def inner_func()
return inner_func()

If you don’t use the keyword return for returning the inner function, it will still return the same result.

When you run this simple code, it will return you the text, defined as the value in the variable ‘msg’.

Output: Hy! I am Aqsa Yasin

Now define the same type of nested function with no return keyword and passing variable ‘msg’ in parameter, and you will get the same output.

Output: Hello

Simple Closure Function

Use the same code, with a little change at the last two lines. With the string ‘Hello’, the show_msg() method was invoked, and the returned method was tied to the word ‘another’. While calling another(), the text ‘Hello’ was still recalled, while the show_msg() method had already been done running. Make sure to add the variable ‘msg’ within the outer function.

When you run this code, it will show that the inner function, which is a show(), has been assigned to the variable ‘another’.

Output: <function show_msg.<locals>.show at 0x0000020CCED4D820>

You can simply print out the name of a function assigned to variable ‘another’ as:


It will output the name of a function.

Output: show

Now, if you want to execute this variable as a function, like other methods, you can do so by adding parenthesis and calling it like this:

another = show_msg("Hello")

You can call this as many times as you wish.

When you run this code, it will display something like this:





Now you can see that even after the finishing of the outer function execution, the inner function still remembers the variables and other things that were created or defined in the local space.

Closure Function using Parameters

Now, we have added parameters while passing a variable in the outer function as:

def show_msg(msg)

The value passed into the outer function parameter will be assigned to a variable defined within this outer function as:

Message = msg

Pass some string values in the newly created variables at the last line, as:

func1 = show_msg(‘Hi’)
func2 = show_msg(‘Hello’)

Now you have to call these functions like this:


You will get the following output shown in the spyder editor image:

Within Python, this process, by which any data (Hi or Hello for this scenario) gets attached to the script, is named Closure.

Simple multiplication using Python Closure

We have defined two functions. One is outer, which has multiplier defined, and the inner in which the value will be passed while calling the function. In the outer function, we have declared a variable with a defined multiplier value passed in it. This multiplier value ‘n’ has been multiplied with some value ‘x’ that is passed in the print statement to the inner function. The inner function is then returned, which is a nested function, and after that, variables have been called one after another in the print statements.

def out_multiply(n):
def in_multiply(x):
return x * n
return in_multiply

Now the new variable has assigned some value to be passed in the parameter of the outer function. This value will be saved in the variable ‘n’, which is a multiplier defined in the outer function:

times3 = out_multiply(3)
times5 = out_multiply(5)

These variables will be assigned with more values, which will be saved into the ‘x’ variable defined in the inner function that needs to be multiplied by multiplier ‘n’. When we print the variable named as ‘times’, a function with some integer value ‘x’ assigned in the parenthesis will make it multiply with the outer function value ’n’.

The first one will output 27 while performing print statement because variable ‘n’ has 3 as a multiplier, and we have given 9 as another integer to be multiplied.


The second one will output 15 while executing the print statement because variable ‘n’ has 3 as a multiplier, and we have given 5 as another integer to be multiplied.


The last one will output 30 while running a print statement because it has recursively called times to function variable. The first time, times has ‘n’ having 3 as a multiplier, which will be multiplied to integer 2. On multiplication, it will output 6. Now, this 6 will be used as a value, then passed as an argument to the times’ variable function, where the ‘n’ variable multiplier is 5. So, when 5 is multiplied by 6 it will output 30.


You can see the output in the console of Spyder editor.


Closures can prohibit global values from being used and have a form of data hiding. It could provide an object or entity oriented approach to the issue as well. Hopefully, after following this guide, you will be able to acquire the fundamentals of Python closure.

About the author

Aqsa Yasin

Aqsa Yasin

I am a self-motivated information technology professional with a passion for writing. I am a technical writer and love to write for all Linux flavors and Windows.