Why arent python nested functions closures?

Nonlocal variable in a nested function

Before getting into what a closure is, we have to first understand what a nested function and nonlocal variable is.

A function defined inside another function is called a nested function. Nested functions can access variables of the enclosing scope.

In Python, these non-local variables are read-only by default and we must declare them explicitly as non-local (using nonlocal keyword) in order to modify them.

Following is an example of a nested function accessing a non-local variable.

def print_msg(msg):
    # This is the outer enclosing function

    def printer():
        # This is the nested function
        print(msg)

    printer()

# We execute the function
# Output: Hello
print_msg("Hello")

Output

Hello

We can see that the nested printer() function was able to access the non-local msg variable of the enclosing function.


Defining a Closure Function

In the example above, what would happen if the last line of the function print_msg() returned the printer() function instead of calling it? This means the function was defined as follows:

def print_msg(msg):
    # This is the outer enclosing function

    def printer():
        # This is the nested function
        print(msg)

    return printer  # returns the nested function


# Now let's try calling this function.
# Output: Hello
another = print_msg("Hello")
another()

Output

Hello

That's unusual.

The print_msg() function was called with the string "Hello" and the returned function was bound to the name another. On calling another(), the message was still remembered although we had already finished executing the print_msg() function.

This technique by which some data ("Hello in this case) gets attached to the code is called closure in Python.

This value in the enclosing scope is remembered even when the variable goes out of scope or the function itself is removed from the current namespace.

Try running the following in the Python shell to see the output.

>>> del print_msg
>>> another()
Hello
>>> print_msg("Hello")
Traceback (most recent call last):
...
NameError: name 'print_msg' is not defined

Here, the returned function still works even when the original function was deleted.


When do we have closures?

As seen from the above example, we have a closure in Python when a nested function references a value in its enclosing scope.

The criteria that must be met to create closure in Python are summarized in the following points.

  • We must have a nested function (function inside a function).
  • The nested function must refer to a value defined in the enclosing function.
  • The enclosing function must return the nested function.

When to use closures?

So what are closures good for?

Closures can avoid the use of global values and provides some form of data hiding. It can also provide an object oriented solution to the problem.

When there are few methods (one method in most cases) to be implemented in a class, closures can provide an alternate and more elegant solution. But when the number of attributes and methods get larger, it's better to implement a class.

Here is a simple example where a closure might be more preferable than defining a class and making objects. But the preference is all yours.

def make_multiplier_of(n):
    def multiplier(x):
        return x * n
    return multiplier


# Multiplier of 3
times3 = make_multiplier_of(3)

# Multiplier of 5
times5 = make_multiplier_of(5)

# Output: 27
print(times3(9))

# Output: 15
print(times5(3))

# Output: 30
print(times5(times3(2)))

Output

27
15
30

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. Referring to the example above, we know times3 and times5 are closure functions.

>>> make_multiplier_of.__closure__
>>> times3.__closure__
(<cell at 0x0000000002D155B8: int object at 0x000000001E39B6E0>,)

The cell object has the attribute cell_contents which stores the closed value.

>>> times3.__closure__[0].cell_contents
3
>>> times5.__closure__[0].cell_contents
5

You'll get an error saying that x is not defined. But how can that be if it has been shown by others that you can print it? This is because of how Python it manages the functions variable scope. While the inner function can read the outer function's variables, it cannot write them., 10 Python 3 has the nonlocal keyword, which is like global but for an outer function's variables. This will allow an inner function to rebind a name from its outer function(s). I think "bind to the name" is more accurate than "modify the variable". – leewz Jan 13, 2016 at 2:04 ,People are confusing about what closure is. Closure is not the inner function. the meaning of closure is act of closing. So inner function is closing over a nonlocal variable which is called free variable.,So when you call counter_in its scope is gone, but it does not matter. because variable initial_value is directly referencing the CELL Obj. and it indirectly references the value of initial_value. That is why even though scope of outer function is gone, inner function will still have access to the free variable

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()

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!

example: of closure attributes but no content inside as there is no free variable.

>>> def foo():
   ...def fii():
   ...pass
   ...
   return fii
      ...
      >>>
      f = foo() >>>
      f.func_closure >>>
      'func_closure' in dir(f)
True
   >>>

I will explain using the same snippet as above:

>>> def make_printer(msg):
   ...def printer():
   ...print msg
   ...
   return printer
      ...
      >>>
      printer = make_printer('Foo!') >>>
      printer() #Output: Foo!

Here is the attribute func_closure for the function printer

>>> 'func_closure' in dir(printer)
True
>>> printer.func_closure
(<cell at 0x108154c90: str object at 0x108151de0>,)
   >>>

Python has a weak support for closure. To see what I mean take the following example of a counter using closure with JavaScript:

function initCounter() {
   var x = 0;

   function counter() {
      x += 1;
      console.log(x);
   };
   return counter;
}

count = initCounter();

count(); 
count(); 
count(); 

Closure is quite elegant since it gives functions written like this the ability to have "internal memory". As of Python 2.7 this is not possible. If you try

def initCounter():
   x = 0;
def counter():
   x += 1 # #Error, x not defined
print x
return counter

count = initCounter();

count();
# #Error
count();
count();

3. Define a simple modifiable class Object

class Object(object):
   pass

In Python 3, support is more explicit - and succinct:

def closure():
   count = 0
def inner():
   nonlocal count
count += 1
print(count)
return inner

Usage:

start = closure()
another = closure() # another instance, with a different stack

start() # prints 1
start() # prints 2

another() # print 1

start() # prints 3

I had a situation where I needed a separate but persistent name space. I used classes. I don't otherwise. Segregated but persistent names are closures.

>>> class f2:
   ...def __init__(self):
   ...self.a = 0
   ...def __call__(self, arg):
   ...self.a += arg
   ...
   return (self.a)
      ...
      >>>
      f = f2() >>>
      f(2)
2
   >>>
   f(2)
4
   >>>
   f(4)
8
   >>>
   f(8)
16

# ** OR **
   >>>
   f = f2() # ** re - initialize **
   >>>
   f(f(f(f(2)))) # ** nested **
   16

# handy in list comprehensions to accumulate values >>>
   [f(i) for f in [f2()]
      for i in [2, 2, 4, 8]
   ][-1]
16

1._

def nested1(num1):
   print "nested1 has", num1
def nested2(num2):
   print "nested2 has", num2, "and it can reach to", num1
return num1 + num2 #num1 referenced
for reading here
return nested2

Gives:

In[17]: my_func = nested1(8)
nested1 has 8

In[21]: my_func(5)
nested2 has 5 and it can reach to 8
Out[21]: 13


Suggestion : 2

A function defined inside another function is called a nested function. Nested functions can access variables of the enclosing scope.,We can see that the nested printer() function was able to access the non-local msg variable of the enclosing function.,The nested function must refer to a value defined in the enclosing function.,Following is an example of a nested function accessing a non-local variable.

Following is an example of a nested function accessing a non-local variable.

def print_msg(msg):
   # This is the outer enclosing
function

def printer():
   # This is the nested
function
print(msg)

printer()

# We execute the
function
# Output: Hello
print_msg("Hello")

In the example above, what would happen if the last line of the function print_msg() returned the printer() function instead of calling it? This means the function was defined as follows:

def print_msg(msg):
   # This is the outer enclosing
function

def printer():
   # This is the nested
function
print(msg)

return printer # returns the nested
function

# Now
let 's try calling this function.
# Output: Hello
another = print_msg("Hello")
another()


Suggestion : 3

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()

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!

example: of closure attributes but no content inside as there is no free variable.

>>> def foo():
   ...def fii():
   ...pass
   ...
   return fii
      ...
      >>>
      f = foo() >>>
      f.func_closure >>>
      'func_closure' in dir(f)
True
   >>>

I will explain using the same snippet as above:

>>> def make_printer(msg):
   ...def printer():
   ...print msg
   ...
   return printer
      ...
      >>>
      printer = make_printer('Foo!') >>>
      printer() #Output: Foo!

Here is the attribute func_closure for the function printer

>>> 'func_closure' in dir(printer)
True
>>> printer.func_closure
(<cell at 0x108154c90: str object at 0x108151de0>,)
   >>>

Python has a weak support for closure. To see what I mean take the following example of a counter using closure with JavaScript:

function initCounter() {
   var x = 0;

   function counter() {
      x += 1;
      console.log(x);
   };
   return counter;
}
count = initCounter();
count(); 
count(); 
count(); 

Closure is quite elegant since it gives functions written like this the ability to have “internal memory”. As of Python 2.7 this is not possible. If you try

def initCounter():
   x = 0;
def counter():
   x += 1 # #Error, x not defined
print x
return counter
count = initCounter();
count();
# #Error
count();
count();

3. Define a simple modifiable class Object

class Object(object):
   pass

In Python 3, support is more explicit – and succinct:

def closure():
   count = 0
def inner():
   nonlocal count
count += 1
print(count)
return inner

Usage:

start = closure()
start() # prints 1
start() # prints 2
start() # prints 3

I had a situation where I needed a separate but persistent name space.
I used classes. I don’t otherwise.
Segregated but persistent names are closures.

>>> class f2:
   ...def __init__(self):
   ...self.a = 0
   ...def __call__(self, arg):
   ...self.a += arg
   ...
   return (self.a)
      ...
      >>>
      f = f2() >>>
      f(2)
2
   >>>
   f(2)
4
   >>>
   f(4)
8
   >>>
   f(8)
16
# ** OR **
   >>>
   f = f2() # ** re - initialize **
   >>>
   f(f(f(f(2)))) # ** nested **
   16
# handy in list comprehensions to accumulate values >>>
   [f(i) for f in [f2()]
      for i in [2, 2, 4, 8]
   ][-1]
16

Answer #6:

def nested1(num1):
   print "nested1 has", num1
def nested2(num2):
   print "nested2 has", num2, "and it can reach to", num1
return num1 + num2 #num1 referenced
for reading here
return nested2

Gives:

In[17]: my_func = nested1(8)
nested1 has 8
In[21]: my_func(5)
nested2 has 5 and it can reach to 8
Out[21]: 13


Suggestion : 4

Tags : pythonclosuresnested-functionpython,And all Python functions have a closure attribute so let's examine the enclosing variables associated with a closure function.,function attributes func_closure in python < 3.X or __closure__ in python > 3.X save the free variables.,function attributes func_closure in python < 3.X or __closure__ in python > 3.X save the free variables.

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()

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!

example: of closure attributes but no content inside as there is no free variable.

>>> def foo(): ...def fii(): ...pass...
   return fii... >>> f = foo() >>> f.func_closure >>> 'func_closure' in dir(f) True >>>

I will explain using the same snippet as above:

>>> def make_printer(msg): ...def printer(): ...print msg...
   return printer... >>> printer = make_printer('Foo!') >>> printer() #Output: Foo!

Here is the attribute func_closure for the function printer

>>> 'func_closure' in dir(printer) True >>> printer.func_closure (<cell at 0x108154c90: str object at 0x108151de0>,) >>>

Python has a weak support for closure. To see what I mean take the following example of a counter using closure with JavaScript:

function initCounter() {
   var x = 0;

   function counter() {
      x += 1;
      console.log(x);
   };
   return counter;
}
count = initCounter();
count(); 

Closure is quite elegant since it gives functions written like this the ability to have "internal memory". As of Python 2.7 this is not possible. If you try

def initCounter(): x = 0;
def counter(): x += 1 # #Error, x not defined print x
return counter count = initCounter();
count();
# #Error count();
count();

3. Define a simple modifiable class Object

class Object(object): pass

In Python 3, support is more explicit - and succinct:

def closure(): count = 0 def inner(): nonlocal count count += 1 print(count) return inner

Usage:

start = closure() another = closure() # another instance, with a different stack start() # prints 1 start() # prints 2 another() # print 1 start() # prints 3

I had a situation where I needed a separate but persistent name space. I used classes. I don't otherwise. Segregated but persistent names are closures.

>>> class f2: ...def __init__(self): ...self.a = 0...def __call__(self, arg): ...self.a += arg...
   return (self.a)... >>> f = f2() >>> f(2) 2 >>> f(2) 4 >>> f(4) 8 >>> f(8) 16 # ** OR ** >>> f = f2() # ** re - initialize ** >>> f(f(f(f(2)))) # ** nested ** 16 # handy in list comprehensions to accumulate values >>> [f(i) for f in [f2()]
      for i in [2, 2, 4, 8]
   ][-1] 16


Suggestion : 5

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?,A closure occurs when a function has access to a local variable from an enclosing scope that has finished its execution.,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.

def make_printer(msg):
   def printer():
   print(msg)
return printer

printer = make_printer('Foo!')
printer()

def make_printer(msg):
   def printer(msg = msg):
   print(msg)
return printer

printer = make_printer("Foo!")
printer() #Output: Foo!


Suggestion : 6

A closure occurs when a function has access to a local variable from an enclosing scope that has finished its execution.,Here’s an example of a nested function which is not a closure.,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.,msg is just a normal local variable of the function printer in this context.

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()

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!


Suggestion : 7

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?,If you are not yet on Python 3.5 or need to write backward-compatible code, and you want this in a single expression, the most performant while the correct approach is to put it in a function:,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.

I have two Python dictionaries, and I want to write a single expression that returns these two dictionaries, merged (i.e. taking the union). The update() method would be what I need, if it returned its result instead of modifying a dictionary in-place.

>>> x = {
      "a": 1,
      "b": 2
   } >>>
   y = {
      "b": 10,
      "c": 11
   } >>>
   z = x.update(y) >>>
   print(z)
None
   >>>
   x {
      "a": 1,
      "b": 10,
      "c": 11
   }

In Python 3.9.0 or greater (released 17 October 2020): PEP-584, discussed here, was implemented and provides the simplest method:

z = x | y # NOTE: 3.9 + ONLY

In Python 3.5 or greater:

In Python 2, (or 3.4 or lower) write a function:

def merge_two_dicts(x, y):
   z = x.copy() # start with keys and values of x
z.update(y) # modifies z with keys and values of y
return z

and now:

z = merge_two_dicts(x, y)

In Python 3.9.0 or greater (released 17 October 2020): PEP-584, discussed here, was implemented and provides the simplest method:

z = x | y # NOTE: 3.9 + ONLY

In Python 3.5 or greater:

In Python 2, (or 3.4 or lower) write a function:

def merge_two_dicts(x, y):
   z = x.copy() # start with keys and values of x
z.update(y) # modifies z with keys and values of y
return z

In your case, what you can do is:

z = dict(list(x.items()) + list(y.items()))

This will, as you want it, put the final dict in z, and make the value for key b be properly overridden by the second (y) dict"s value:

>>> x = {
      "a": 1,
      "b": 2
   } >>>
   y = {
      "b": 10,
      "c": 11
   } >>>
   z = dict(list(x.items()) + list(y.items())) >>>
   z {
      "a": 1,
      "c": 11,
      "b": 10
   }

If you use Python 2, you can even remove the list() calls. To create z:

>>> z = dict(x.items() + y.items()) >>>
   z {
      "a": 1,
      "c": 11,
      "b": 10
   }


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.

Does Python allow closures?

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.

Are nested functions allowed in Python?

If you define a function inside another function, then you're creating an inner function, also known as a nested function. In Python, inner functions have direct access to the variables and names that you define in the enclosing function.

Are nested functions bad?

One disadvantage of declaring a nested function is the fact that it will be created inside function's environment every time you call the parent function. In theory, this could decrease performance if the parent function is called frequently. But, nested functions are very much used in Javascript.