A closure occurs when a function has access to a local variable from an enclosing scope that has finished its execution.
def make_printer(msg):
def printer():
print msg
return printer
printer = make_printer('Foo!')
printer()
When make_printer
is called, a new frame is put on the stack with the compiled code for the printer
function as a constant and the value of msg
as a local. It then creates and returns the function. Because the function printer
references the msg
variable, it is kept alive after the make_printer
function has returned.
So, if your nested functions don't
- access variables that are local to enclosing scopes,
- do so when they are executed outside of that scope,
then they are not closures.
Here's an example of a nested function which is not a closure.
def make_printer(msg):
def printer(msg=msg):
print msg
return printer
printer = make_printer("Foo!")
printer() #Output: Foo!
Here, we are binding the value to the default value of a parameter. This occurs when the function printer
is created and so no reference to the value of msg
external to printer
needs to be maintained after make_printer
returns. msg
is just a normal local variable of the function printer
in this context.