Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why aren't python nested functions called closures?

I have seen and used nested functions in Python, and they match the definition of a closure. So why are they called nested functions instead of closures?

Are nested functions not closures because they are not used by the external world?

UPDATE: I was reading about closures and it got me thinking about this concept with respect to Python. I searched and found the article mentioned by someone in a comment below, but I couldn't completely understand the explanation in that article, so that is why I am asking this question.

like image 354
Srikar Appalaraju Avatar asked Oct 26 '10 03:10

Srikar Appalaraju


People also ask

Is nested function a closure?

Now what are closures? Closures - the nested functions continue to live even when the outer function has completed is closure. The day to day way in which we are able to see closure is callbacks.

Are there closures in Python?

Python Decorators make an extensive use of closures as well. On a concluding note, it is good to point out that the values that get enclosed in the closure function can be found out. All function objects have a __closure__ attribute that returns a tuple of cell objects if it is a closure function.

Why are closures called closures?

A closure is a function and its scope assigned to (or used as) a variable. Thus, the name closure: the scope and the function is enclosed and used just like any other entity.

Why do we use closures in Python?

Python Closures are these inner functions that are enclosed within the outer function. Closures can access variables present in the outer function scope. It can access these variables even after the outer function has completed its execution.


1 Answers

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

  1. access variables that are local to enclosing scopes,
  2. 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.

like image 130
aaronasterling Avatar answered Sep 27 '22 01:09

aaronasterling