1
def raise_val(n):
    """Return the inner function."""

    def inner(x):
    """Raise x to the power of n."""
        raised = x ** n
        return raised

    return inner

square = raise_val(2)

cube = raise_val(3)

print(square(2), cube(4))

Outputs:

4 64

Can anybody explain to me how come square(2) knows that the argument passed is x?

4
  • because you can always access variables from outer scope and n is in the scope of raise_val, which is an outer scope of inner Here is more info: datacamp.com/community/tutorials/scope-of-variables-python Commented Jun 4, 2020 at 11:02
  • 1
    What do you mean? x is just a name. Bottom line is you call square with the argument 2. In that case square is equivalent to the function inner with the value of n being 2. So the argument 2 of square is "passed on" to inner, which happens to be called x... Commented Jun 4, 2020 at 11:04
  • Can you please clarify your question? What do you mean by "square(2) knows that the argument passed is x"? Argument binding works exactly the same for top-level and nested functions. square is an alias for a specific def inner(x):, which "knows" its argument is x just like raise_value "knows" its argument is n. Commented Jun 4, 2020 at 11:22
  • raise_val(n) returns a function of x, inner(x), which has been specified by n. When you call square(2) you're really calling a specific version of inner(x), which is equivalent to raise_val(n)(x). Commented Jun 4, 2020 at 12:09

2 Answers 2

1

this code uses the concept of lexical closures or closures.Closures are the function that remembers the parameters passed to their parent function.The more technical definition will be,Closures are the function that remembers values in enclosing scope even if they are not actually present in the memory.

#for example`
def outer(x):
    def inner():
        print(f"The argument passed to outer was {x}")
    '''Notice how inner() will grab the argument passed to the outer function'''

     return inner

value=outer(69)

print(value())
Sign up to request clarification or add additional context in comments.

Comments

1

Maybe this will help: https://stackabuse.com/python-nested-functions/

Notice you "sends arguments twice" (not really): first in square = raise_val(2) and second in square(2). What happens? The first calls return a function: you call to raise_val and it returns inner, which is a function. Now square variable actually holds a function. Second call, square(2), just call to the function.

It's the same as:

def a(x):
   print(x)

square = a 
print(square(5))

In this example, square holds a function. It's the same as in your code, since raise_val returns a function. Square holds inner method, and later it is been called. You send x directly: square(2) sends 2 for x of course. A more interesting can be "how inner remembers n?", and as others mentioned in comments: it's manages variables of current scope.

2 Comments

Thanks for your answers, so it means that square = raise_val(2) here square holds the function raise_val(n) and when you pass arguments to square for eg. square(2) it knows that it is for inner(x).
no. square = raise_val(2) does not the function raise_val(n), it calls the function and hold what the function returns. If raise_val ended with return 9, variable square will hold 9. Since it returns a function, square holds a function. The second part of what you said is correct.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.