473,406 Members | 2,894 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

When Closure get external variable's value?

What will the following piece of code print? (10 or 15)

def testClosure(maxIndex) :

def closureTest():
return maxIndex

maxIndex += 5

return closureTest()

print testClosure(10)

My question is when the closure function gets value for maxindex? Run
time or compile time?

Thanks.

Dec 18 '06 #1
11 2996
It will print 15. The closure gets the value at run time.

Could we treat closure as part of the external function and it shares
the local variable with its holder function?

Dec 18 '06 #2
Huayang Xia kirjoitti:
It will print 15. The closure gets the value at run time.

Could we treat closure as part of the external function and it shares
the local variable with its holder function?
I don't quite get what you are trying to tell us but if you think that
in your example code:

def testClosure(maxIndex) :

def closureTest():
return maxIndex

maxIndex += 5

return closureTest()

print testClosure(10)

you are returning a callable function you are all wrong. This can be
easily seen by:
>>type(testClosure(10))
15
<type 'int'>

The mistake is that you shouldn't return closureTest() but closureTest
instead. The correct way would be:
>>def testClosure2(maxIndex):
def closureTest():
return maxIndex
maxIndex += 5
return closureTest
>>f2 = testClosure2(10)
<function closureTest at 0x00D82530>
>>type(f2)
<type 'function'>
>>print f2()
15

Cheers,
Jussi
Dec 18 '06 #3
Thanks for the clarification.

But my question is:

When does the closure get the value of the maxIndex in the following
code snippet?

def testClosure(maxIndex) :

def closureTest():
return maxIndex

maxIndex += 5

return closureTest()

print testClosure(10)
I thought it should be 10 instead of 15. That was wrong.

After several tests, I found maxIndex is, though, local to
testClosure() but is external to the closureTest(). closureTest() gets
the value of maxIndex at run time. So that it's 15 instead of 10. The
following snippet will verify that further:

def testClosure1(lst):

def closureTest():
lst.append(lst[-1]+1)

lst.append(lst[-1]+1)
return closureTest()

alist = [1]
testClosure1(alist)
alist.append(3)
testClosure1(alist)

The 'lst' in function testClosure1() and the closure closureTest() are
same thing as alist. So everything is dynamic. Variable's value is
determined at run time.

Dec 19 '06 #4
Huayang Xia wrote:
When does the closure get the value of the maxIndex in the following
code snippet?

def testClosure(maxIndex) :

def closureTest():
return maxIndex

maxIndex += 5

return closureTest()

print testClosure(10)
I thought it should be 10 instead of 15. That was wrong.
free variables in an inner scope bind to variables in the outer scope,
not objects.

if you want to bind to objects, use explicit binding:

def closureTest(maxIndex=maxIndex):
return maxIndex

</F>

Dec 19 '06 #5
That is a really concise and precise answer. Thanks.

So the object binding can only happen explicitly at the closure
declaration argument list(non-free variable).

On Dec 19, 10:37 am, Fredrik Lundh <fred...@pythonware.comwrote:
Huayang Xia wrote:
When does the closure get the value of the maxIndex in the following
code snippet?
def testClosure(maxIndex) :
def closureTest():
return maxIndex
maxIndex += 5
return closureTest()
print testClosure(10)
I thought it should be 10 instead of 15. That was wrong.free variables in an inner scope bind to variables in the outer scope,
not objects.

if you want to bind to objects, use explicit binding:

def closureTest(maxIndex=maxIndex):
return maxIndex

</F>
Dec 19 '06 #6
In <11**********************@t46g2000cwa.googlegroups .com>, Huayang Xia
wrote:
That is a really concise and precise answer. Thanks.

So the object binding can only happen explicitly at the closure
declaration argument list(non-free variable).
That's no declaration that's a definition and it happens at runtime! It's
executed every time the outer function is called and executed and creates
a function object.

As far as I can see you don't create a closure BTW. You are *calling*
that inner function and return the *result* of that call.

Ciao,
Marc 'BlackJack' Rintsch
Dec 19 '06 #7
I'm confused. What is the definition of closure.

I'm not sure if it's correct, I get the definition from wikipedia:

"A closure typically comes about when one function is declared entirely
within the body of another, and the inner function refers to local
variables of the outer function. At runtime, when the outer function
executes, a closure is formed. It consists of the inner function's code
and references to any variables in the outer function's scope that the
closure needs."

I agree it is not declaration, it's definition. However it's closure
based on the above definition. It uses free variable. Or you mean it's
a closure only when the outer function returns it and be exposed to
external world?

The code snippet was just for test purpose. My question was how the
free variable inside inner function (the closure) binds with object.
That was answered by Fredrik perfectly.

Dec 19 '06 #8
Huayang Xia a écrit :
I'm confused. What is the definition of closure.

I'm not sure if it's correct, I get the definition from wikipedia:

"A closure typically comes about when one function is declared entirely
within the body of another, and the inner function refers to local
variables of the outer function. At runtime, when the outer function
executes, a closure is formed. It consists of the inner function's code
and references to any variables in the outer function's scope that the
closure needs."
You skipped the first and most important sentence:
"In programming languages, a closure is a function that refers to free
variables in its lexical context."

IOW, a closure is a function that carry it's own environment. In the
following code, the function returned by make_adder is a closure :

def make_adder(adding):
def adder(num):
return num + adding
return adder
add_three = make_adder(3)
print add_three(4)
=7
I agree it is not declaration, it's definition. However it's closure
based on the above definition. It uses free variable.
Actually, it uses a variable defined in the enclosing scope. But as long
as it's also executed in the same enclosing scope, it's just a nested
function.
Or you mean it's
a closure only when the outer function returns it and be exposed to
external world?
Bingo.
Dec 19 '06 #9
Bruno Desthuilliers wrote:
>You skipped the first and most important sentence:
"In programming languages, a closure is a function that refers to free
variables in its lexical context."

IOW, a closure is a function that carry it's own environment.
in contrast to functions that don't know what environment they belong
to, you mean ? can you identify such a construct in Python ?

</F>

Dec 19 '06 #10
My understanding was:

Closure is a nested function first. If it refers free variable, then it
is closure. If it doesn't refer free variable, it doesn't have to be
nested. That is probably the reason, the free variable is emphasized.
Normally it makes sense to return a closure, but not a non-closure
nested function.

I don't understand why while a nested function perfectly matches the
definition of closure, it is not closure simply because it is not used
by external world.

BTW, IMHO, The meaning of the "most important sentence" was contained
in the original quote. That was the reason I skipped it.

On Dec 19, 4:14 pm, Bruno Desthuilliers
<bdesth.quelquech...@free.quelquepart.frwrote:
Huayang Xia a écrit :
I'm confused. What is the definition of closure.
I'm not sure if it's correct, I get the definition from wikipedia:
"A closure typically comes about when one function is declared entirely
within the body of another, and the inner function refers to local
variables of the outer function. At runtime, when the outer function
executes, a closure is formed. It consists of the inner function's code
and references to any variables in the outer function's scope that the
closure needs."You skipped the first and most important sentence:
"In programming languages, a closure is a function that refers to free
variables in its lexical context."

IOW, a closure is a function that carry it's own environment. In the
following code, the function returned by make_adder is a closure :

def make_adder(adding):
def adder(num):
return num + adding
return adder

add_three = make_adder(3)
print add_three(4)
=7
I agree it is not declaration, it's definition. However it's closure
based on the above definition. It uses free variable.Actually, it uses a variable defined in the enclosing scope. But as long
as it's also executed in the same enclosing scope, it's just a nested
function.
Or you mean it's
a closure only when the outer function returns it and be exposed to
external world?Bingo.
Dec 19 '06 #11
Huayang Xia wrote:
I don't understand why while a nested function perfectly matches the
definition of closure, it is not closure simply because it is not used
by external world.
Like so many other computing terms, the word "closure" is used in
different ways by different people.

Strictly speaking, a closure is simply a function with free variables,
where the bindings for all such variables are known in advance. Some
early languages didn't have "closed" functions; the bindings for free
variables were left open, and was determined at runtime. And languages
that had both "open" and "closed" functions needed some way to
distinguish between the two, so people started referring to the latter
as "closures".

But in Python, as well as in most other modern languages, all functions
are "closed" -- i.e. there are no "open" free variables -- so the use of
the term has morphed from "a function for which all free variables have
a known binding" to "a function that can refer to environments that are
no longer active" (such as the local namespace of an outer function,
even after that function has returned). And since *that* is somewhat
difficult to implement, and programmers don't like to hide things that
are hard to implement, people still like to use the term to distinguish
between closed functions of kind 1 and closed functions of kind 2. As
in this thread, they sometimes argue that when you're using a closed
function of kind 2 in a specific way, it's not quite as much of a
closure as when you use it in another way. Heck, some people even argue
that languages that don't support closed functions of kind 3 (a kind
that Python currently doesn't support) don't really have closures at all.

But as a language user, you can actually forget about all this -- all
you need to know is that in Python, all functions are closed, and free
variables bind to *variable names* in lexically nested outer scopes.

</F>

Dec 19 '06 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

27
by: Ted Lilley | last post by:
What I want to do is pre-load functions with arguments by iterating through a list like so: >>>class myclass: .... pass >>>def func(self, arg): .... print arg >>>mylist = >>>for item...
1
by: mr_burns | last post by:
Hi, i was wondering if it is possible to load text into a string from an external text file. the reason is that i have a very large string and it is making my script very messy. also, is it...
2
by: Harry Stangel | last post by:
Noble reader, My goal is to obtain the current time on the web server and display it in the client's browser. I want the server time displayed independent of the client's current clock setting,...
2
by: f rom | last post by:
----- Forwarded Message ---- From: Josiah Carlson <jcarlson@uci.edu> To: f rom <etaoinbe@yahoo.com>; wxpython-users@lists.wxwidgets.org Sent: Monday, December 4, 2006 10:03:28 PM Subject: Re: ...
0
by: Gerard Brunick | last post by:
Consider: ### Function closure example def outer(s): .... def inner(): .... print s .... return inner .... 5
2
by: Bob.Sidebotham | last post by:
If I run the following code: class path(object): def __init__(self, **subdirs): for name, path in subdirs.iteritems(): def getpath(): return path setattr(self, name, getpath) export = path(
0
by: =?Utf-8?B?SlA=?= | last post by:
I have an application that uses Forms Authentication in connection with Active Directory for granting access to an application. When a user logs on with AD, it populates the AUTH_USER...
7
by: howardk | last post by:
I'm writing some code that loads a number of images, using the standard mechanism of assigning a src url to a newly constructed Image object, thus invoking the image-load operation. On a successful...
3
by: disappearedng | last post by:
Hi everyone I am currently reading a book, and I don't seem to under the author, (Crockfold) when he says this: //Bad examples var add_the_handlers = function(nodes){ var i; for (i = 0; i <...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.