Function binding in python

Viewed 97
n = 7

def f(x):
    n = 8
    return x + 1

def g(x):
    n = 9
    def h():
        return x + 1
    return h

def f(f, x):
    return f(x + n)

f = f(g, n)
g = (lambda y: y())(f)

I'm trying to understand and keep track of all the changes in the binding of functions, but cannot seem to grasp why the y parameter in the lambda function gets binded to h() on being called.

The transition from step 14-15 in this Python Tutor link to be precise

1 Answers

Let's change the names of the functions so that twisted code is easier to follow. We can name then sequentially like fun_n and reassign the names after each function definition. I added some comments too

The first one would be

n = 7

def fun_1(x):
    n = 8
    return x + 1
f = fun1

The second one:

def fun_2(x):
    n = 9
    def h():
        return x + 1
    return h
g = fun_2

Now we are ready for some bad renaming

def fun_3(f, x):
    return f(x + n)
f = fun_3

And now...

f = f(g, n)

which is equivalent to fun_3(fun2, n) with n=7. fun_3 will return fun_2(7+n), again with n=7. fun_2 will return a closure of h with x=14, so it will return a function that returns the result of 14 + 1. So f is now a function that always return 15

Finally,

g = (lambda y: y())(f)

creates a lambda function that calls whatever parameter is passed to it, and calls it passing f as a parameter. It is equivalent to:

fun_4 = lambda y: y()
g = fun_4(f)

I don't think it is really useful as an excercise.

Related