I just don't understand, we never define param b in the inner function, but why would the inner function accept a b without error?
def test(a):
def add(b):
nonlocal a
a = 1
return a b
return add
func = test(4)
print(func(4))
the above function comes from here: https://www.w3resource.com/python-exercises/python-functions-exercise-19.php
CodePudding user response:
Here's what's happening in this function:
- Line 1 creates
test()
, which is a closure factory function. This means that it creates a new closure each time it’s called and then returns the closure to the caller. - Line 2 defines
add()
, which is an inner function that takes a single argument, base, and returns the result of the expressiona*b
. - Line 6 returns
add()
as a function object, without calling it.
The question now is where does add()
get the value of a
from? This is where the closure comes into play. add()
gets the value of a
from the outer function, test()
. Here’s what Python does when you call test()
in line 9:
- Define a new instance of
add()
, which takes a single argument base. - Take a snapshot of the surrounding state of
add()
, which includesa
with its current value (in line 9 you are defining it asa = 4
). - Return
add()
along with its whole surrounding state.
This way, when you call the instance of add()
returned by test()
in line 10, you’ll see that the function remembers the value of a
! So what you have is the previously assigned value of a = 4
(line 9), and the newly passed argument - the value of b = 4
(line 10).
Hope this helps to clarify!
CodePudding user response:
The way how it is written, is a typical way to access a function defined within a function. This is done by returning the desired function when the main function is called. For instance: see below your code with two functions defined within function TEST() and one of them is called:
def test(a):
def times(b):
nonlocal a
return a*b
def add(b):
nonlocal a
a = 1
return a b
return times
func = test(4) print(func(4))
in this case the ouput is 16.
CodePudding user response:
You're passing b
in this call: func(4)
.
To be clear, func
is add
.
CodePudding user response:
test
will create and return a function with one callee that adds one to a and add it to the callee