Closures is a programming concept that took me a while to wrap my head around. To understand closures you need to understand function scope and factory functions. In the example below, x is accessible in the global scope. You can reference x inside and outside the function. However, y and z are accessible only within the local scope of the function foo. So you can reference x, y and z inside the function, but you can’t reference y and z outside of the function.

x = 3
def foo(y):
	z = 1
	return(x+y+z)

# usage
foo(2)

A factory function is simply a function that returns another function. In the example below A is a factory function that generates function B every time it is executed. Function B references the argument x that is defined in function A . So when we call f = A(4) the function will persist the value x=4, so it can do the operation x+y that when we execute f(3). So function B has access to the the scope of its enclosing function, function A, even after function A has finished executing. This is a closure. This is different from the function foo defined above, where all local variables (y and z ) are eliminated after the function finishes its execution.

def A(x):
	def B(y):
		return(x+y)
	return(B)

# usage
f = A(4)
f
f(3)
f(1)

To tie it to a formal definition, a closure allows the variables defined in the enclosing scope of the function to persist even after the enclosing function has executed.

For reference, here are some useful links: