I am reading the book for web2py. It is running through some python syntax examples. When I ge to this closure example I am not understanding how 'y' gets its value.

This is the code.

 >>> def f(x):
 def g(y):
 return x * y
 return g
 >>> doubler = f(2) # doubler is a new function
 >>> tripler = f(3) # tripler is a new function
 >>> quadrupler = f(4) # quadrupler is a new function
 >>> print doubler(5)
 10
 >>> print tripler(5)
 15
 >>> print quadrupler(5)
 20

so when they create doubler

doubler = f(2)

y gets the value of 2 when this new function is created. However f(2) is from f(x). This is where my confusion is, how does y get its value from x?

Recommended Answers

All 6 Replies

Well, when you set doubler = f(2) that just create a function which parameter is x
so doubler is a function object. now the x is set to be 2, you can change it.
When you type

print doubler(5)

5 is the y. so you get the result 10.

But how does y get the value?

I can't tell what your code looks like because it is not indented.

doubler is now f(2) = return g so that is removed and the value from doubler(5) gets assigned to y that is why you get the x*y value and not "function g at blah blah" which is what the return g would print. Add some print statements

def f(x):
    print " f entered", x
    def g(y):
        print "g executed", y
        return x * y
     return g

doubler = f(2)
print doubler(5)


## if you want to look at it like this: doubler as f(2) =
x = 2
def g(y):
    return x * y

Another look at closure ...

''' closure102.py
A nested function has access to the environment in which it was defined.
This definition occurs during the execution of the outer function.
In a closure you return the reference to the inner function that remembers
the state of the outer function, even after the outer function has completed
execution.
'''

def outer(x):
    def inner(y):
        return x * y
    # return reference to the inner function
    return inner

# inner remembers x = 2
inner = outer(2)

print(inner)
print('-'*30)
# this call will supply the y = 7
print(inner(7))

''' result (location in memory) ...
<function inner at 0x02C4D738>
------------------------------
14
'''

Some good example over,one more.
Running it interactive can help.
I keep function out from interactive environment,then it's eaiser to keep indentation.

def foo(x):
    print 'foo got called with argument', x
    def wrapped(y):
        return x * y
    return wrapped

Run it.

>>> foo
<function foo at 0x02AA1DB0>
>>> #Memory location of uncalled foo  

>>> foo(4)
foo got called with argument 4
<function wrapped at 0x029955B0>
>>> #We see foo get called and we get memory location of uncalled wrapped

>>> foo(4)(5)
foo got called with argument 4
20
>>> #Both function is called

>>> #So store it in a varible
>>> bar = foo(4)
foo got called with argument 4
>>> #So to get the same as over foo(4)(5)
>>> bar(5)
20

Thank You so much for the great replies. I was really struggling to grasp this concept.

>>> foo(4)(5)
foo got called with argument 4
20
>>> #Both function is called
>>> #So store it in a varible
>>> bar = foo(4)
foo got called with argument 4
>>> #So to get the same as over foo(4)(5)
>>> bar(5)
20

This example I think is the one where it really fell into place.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.