1,105,197 Community Members

Not Understanding Passing values in Closure

Member Avatar
flebber
Junior Poster in Training
71 posts since Aug 2009
Reputation Points: 12 [?]
Q&As Helped to Solve: 4 [?]
Skill Endorsements: 1 [?]
 
0
 

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?

Member Avatar
aswekown
Newbie Poster
7 posts since Jan 2013
Reputation Points: 0 [?]
Q&As Helped to Solve: 3 [?]
Skill Endorsements: 0 [?]
 
0
 

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.

Member Avatar
flebber
Junior Poster in Training
71 posts since Aug 2009
Reputation Points: 12 [?]
Q&As Helped to Solve: 4 [?]
Skill Endorsements: 1 [?]
 
0
 

But how does y get the value?

Member Avatar
woooee
Posting Maven
2,792 posts since Dec 2006
Reputation Points: 783 [?]
Q&As Helped to Solve: 836 [?]
Skill Endorsements: 12 [?]
 
4
 

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
Member Avatar
vegaseat
DaniWeb's Hypocrite
6,984 posts since Oct 2004
Reputation Points: 1,544 [?]
Q&As Helped to Solve: 1,872 [?]
Skill Endorsements: 67 [?]
Moderator
 
3
 

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
'''
Member Avatar
snippsat
Veteran Poster
1,039 posts since Aug 2008
Reputation Points: 483 [?]
Q&As Helped to Solve: 381 [?]
Skill Endorsements: 10 [?]
 
2
 

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
Member Avatar
flebber
Junior Poster in Training
71 posts since Aug 2009
Reputation Points: 12 [?]
Q&As Helped to Solve: 4 [?]
Skill Endorsements: 1 [?]
 
0
 

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.

Question Answered as of 1 Year Ago by aswekown, vegaseat, woooee and 1 other
You
This question has already been solved: Start a new discussion instead
Post:
Start New Discussion
View similar articles that have also been tagged: