473,408 Members | 2,813 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,408 software developers and data experts.

Nested function scope problem

I found that I was repeating the same couple of lines over and over in
a function and decided to split those lines into a nested function
after copying one too many minor changes all over. The only problem is
that my little helper function doesn't work! It claims that a variable
doesn't exist. If I move the variable declaration, it finds the
variable, but can't change it. Declaring the variable global in the
nested function doesn't work either.

But, changing the variable in the containing scope is the whole purpose
of this helper function.

I'm new to python, so there is probably some solution I haven't
encountered yet. Could you please suggest a nice clean solution? The
offending code is below. Thanks.

def breakLine(s):
"""Break a string into a list of words and symbols.
"""
def addTok():
if len(tok) 0:
ls.append(tok)
tok = ''

ls = []
tok = ''
splitters = '?()&|:~,'
whitespace = ' \t\n\r'

for c in s:
if c in splitters:
addTok()
ls.append(c)
elif c in whitespace:
addTok()
else:
tok = tok + c

addTok()

return ls

#some tests to make sure it works
print breakLine('carolina(Prada):cat(X,Y)')
print breakLine('trouble :bird (X ) &cat ( Y )')
print breakLine('?trouble')

Jul 22 '06
78 4873
On 2006-07-28 15:20:52, Antoon Pardon wrote:
>Typically, "variable" implies a data storage location that can take on
different values. Emphasis on "location" -- the name is fixed to a
memory location whose contents can be varied.

That is not true. It may be the case in a number of languages but my
experience with lisp and smalltalk, though rather limited, says that no
such memory location is implied with the word "variable" in those
languages and AFAIK they don't have a problem with the word "variable"
either.
>In Python, the closest would be a mutable object.
Maybe this gets somewhere. Consider variable != constant. Python names are
variables in that what they refer to (what is associated with them through
a dict) can be changed, through various means (most commonly assignment).
They are also variables in that what they refer to (usually) can be
changed. Whether an assignment or some other command changes the reference
association or the referenced object is one of the confusing issues with
Python. But that doesn't make a variable less variable... :)

Gerhard

Jul 28 '06 #51
On 2006-07-28 14:32:59, Dennis Lee Bieber wrote:
On Fri, 28 Jul 2006 11:41:30 -0300, Gerhard Fiedler <ge*****@gmail.com>
declaimed the following in comp.lang.python:
>wondered (this is slightly related) is whether it wouldn't be really good
to make the difference between mutable and immutable objects more obvious.

For the most part, a mutable object is one in which you can "go inside"
-- though tuples cross the boundary (you can "go inside" to fetch an
element, but you cant change the inside).
It's the "for the most part" part that I was wondering about :)

So is this correct: It's mutable if you can "go inside", that is, it has an
accessor attached to the name. Unless it's a tuple, in which case it's
immutable even though it has accessors attached. Otherwise, it is
immutable.

Or said in another way: Everything is immutable, except that collections of
objects (classes, lists, etc) may provide means to rebind members, which
then can be considered means to change objects.

I seem to slowly wrap my mind around this... :)

Gerhard

Jul 28 '06 #52
On 2006-07-29, Dennis Lee Bieber <wl*****@ix.netcom.comwrote:
On 28 Jul 2006 17:48:03 GMT, Antoon Pardon <ap*****@forel.vub.ac.be>
declaimed the following in comp.lang.python:
>>
That is no reason to say that python has no variables. If someone would
explain the difference between objects in some other language and
objects in python I wouldn't accept the statement: "python has no
objects" either.
Python objects can exist without a "variable" bound to them...
Though typically such would soon be garbage collected <G>
Well C++ objects can exist without a "variable" bound to them.
We just call them memory leaks <G>
Traditional languages are the other way around... If a variable
exists, it may exist with no object/value (ie, it is uninitialized -- a
big problem in C).
What do you call traditional? Lisp is about as old as Fortran AFAIK.
Python names can not exist (and be used) without
being bound to some object (even None is a defined object). Attempting
to use a name that has not been bound gives you the "unbound local" type
problem.
Yes, some other languages do define special flag values so that they
can detect the usage of an uninitialized item... But the variable itself
exists regardless; you can not detach the object from the variable
(except by assigning something else to the variable).
I'm not so sure Python is that different. The fact that you get
an UnboundLocalError, instead of a NameError, suggests that in
the first case, the 'variable' already exists but is bound to
a "Not yet Bound" value. Not so long ago I was discussing some
implementation details of CPython and someone then said that
all local variables are entered into the local scope at call
time. This was to prevent the language to find variables
that are shadowed on a more global scope because the local
variable wasn't boud yet.

--
Antoon Pardon
Jul 29 '06 #53
On 2006-07-28, Gerhard Fiedler <ge*****@gmail.comwrote:
On 2006-07-28 15:20:52, Antoon Pardon wrote:
>>Typically, "variable" implies a data storage location that can take on
different values. Emphasis on "location" -- the name is fixed to a
memory location whose contents can be varied.

That is not true. It may be the case in a number of languages but my
experience with lisp and smalltalk, though rather limited, says that no
such memory location is implied with the word "variable" in those
languages and AFAIK they don't have a problem with the word "variable"
either.
>>In Python, the closest would be a mutable object.

Maybe this gets somewhere. Consider variable != constant. Python names are
variables in that what they refer to (what is associated with them through
a dict) can be changed, through various means (most commonly assignment).
They are also variables in that what they refer to (usually) can be
changed. Whether an assignment or some other command changes the reference
association or the referenced object is one of the confusing issues with
Python. But that doesn't make a variable less variable... :)
I think the important thing to remember is that the assignment in Python
is a alias maker and not a copy maker. In languages like C, Fortran,
pascal, the assignment makes a copy from what is on the righthand and
stores that in the variable on the lefthand. In languages like Lisp,
Smalltalk and Python, the assignment essentially makes the lefthand
an alias for the righthand.

--
Antoon Pardon
Jul 29 '06 #54
On 2006-07-29, Dennis Lee Bieber <wl*****@ix.netcom.comwrote:
On 28 Jul 2006 18:20:52 GMT, Antoon Pardon <ap*****@forel.vub.ac.be>
declaimed the following in comp.lang.python:

>That is not true. It may be the case in a number of languages but
my experience with lisp and smalltalk, though rather limited,
says that no such memory location is implied with the word "variable"
in those languages and AFAIK they don't have a problem with the
word "variable" either.
I have no smalltalk experience, and my lisp goes back to a cassette
based version on a TRS-80 Model III...

Since, at that time at least, everything in lisp was a
tree-branching linked list I had trouble even considering setq to define
a "variable" -- it was closer to adding a name to a node of the lists...
<G{Yes, that IS a very loose interpretation}

Does lisp permit one object to have multiple "variables" attached to
it -- that is, two or more names on one "object" (whatever the node
contains)...
AFAIK, yes
And if so, what happens if, say, the "object" had been a
scalar value "3.14159265436" perhaps and you make an "assignment" to one
of the names?
About the same as happens in Python. One name will then be attached to
a new "value" and the other names will still be attached to "3.14159265436"

--
Antoon Pardon
Jul 29 '06 #55
On 2006-07-29 13:47:37, Antoon Pardon wrote:
I think the important thing to remember is that the assignment in Python
is a alias maker and not a copy maker. In languages like C, Fortran,
pascal, the assignment makes a copy from what is on the righthand and
stores that in the variable on the lefthand. In languages like Lisp,
Smalltalk and Python, the assignment essentially makes the lefthand
an alias for the righthand.
Yes, I think I got it now :)

It seems that, in essence, Bruno is right in that Python doesn't really
have variables. Everything that seems variable doesn't really change; what
changes is that an element of what seems to change gets rebound. Which in
itself is a rebinding process of a dictionary... I have yet to go there and
see whether anything at all changes :)

Gerhard

Jul 29 '06 #56
On 2006-07-29, Gerhard Fiedler <ge*****@gmail.comwrote:
On 2006-07-29 13:47:37, Antoon Pardon wrote:
>I think the important thing to remember is that the assignment in Python
is a alias maker and not a copy maker. In languages like C, Fortran,
pascal, the assignment makes a copy from what is on the righthand and
stores that in the variable on the lefthand. In languages like Lisp,
Smalltalk and Python, the assignment essentially makes the lefthand
an alias for the righthand.

Yes, I think I got it now :)

It seems that, in essence, Bruno is right in that Python doesn't really
have variables. Everything that seems variable doesn't really change; what
changes is that an element of what seems to change gets rebound.
Aren't you looking too much at implementation details now?

The difference between an alias assignment and a storage assigment
is for instance totaly irrelevant for immutable objects/values like numbers.

On a language level you can't distinghuish between immutable types
where the implementation uses storage assignment or alias assignment
and a number of language implementation do use different implementation
for different types because of optimisation considerations.

AFAIU, one can also build a C++ class hierarchy that with some small
limitations in used operators, would have semantics very similar to
Python. Would you argue that those using such a C++ class hierarchy would
no longer be using variables in C++?

--
Antoon Pardon
Jul 30 '06 #57
On 2006-07-30 09:54:14, Antoon Pardon wrote:
Aren't you looking too much at implementation details now?
Possibly, but at this point I'm still trying to understand how Python does
these things, and what the useful abstraction level is for me. I also still
have very little experience how I'll put the things we've been discussing
here into (Python) practice. While not new to programming, I'm new to
Python.
AFAIU, one can also build a C++ class hierarchy that with some small
limitations in used operators, would have semantics very similar to
Python. Would you argue that those using such a C++ class hierarchy would
no longer be using variables in C++?
Probably not. But for me it's mostly about useful terminology, not
necessarily "correct" terminology. In order to talk about correct
terminology, we'd have to use a common definition of "variable". This is a
term so widely used that I'm not sure there is a useful single definition
of it; do you know one?

In any case, the following doesn't seem to be implementation detail (and
rather a part of the language), but it's not really understandable with a
C++ concept of "variable":
>>a=3
id(a)
3368152
>>b=a
id(b)
3368152
>>b=4
id(b)
3368140

You don't expect the "identity" of the variable b to change with a simple
assignment from a C/C++ point of view. You also don't expect the "identity"
of a and b to be the same after assigning one to the other. You can create
C++ classes that behave like that (you can implement Python in C++ :), but
that doesn't mean that you expect C++ language constructs to behave like
that.

Gerhard

Jul 30 '06 #58
On 2006-07-30, Gerhard Fiedler <ge*****@gmail.comwrote:
On 2006-07-30 09:54:14, Antoon Pardon wrote:
>Aren't you looking too much at implementation details now?

Possibly, but at this point I'm still trying to understand how Python does
these things, and what the useful abstraction level is for me. I also still
have very little experience how I'll put the things we've been discussing
here into (Python) practice. While not new to programming, I'm new to
Python.
>AFAIU, one can also build a C++ class hierarchy that with some small
limitations in used operators, would have semantics very similar to
Python. Would you argue that those using such a C++ class hierarchy would
no longer be using variables in C++?

Probably not. But for me it's mostly about useful terminology, not
necessarily "correct" terminology. In order to talk about correct
terminology, we'd have to use a common definition of "variable". This is a
term so widely used that I'm not sure there is a useful single definition
of it; do you know one?
A name in a scope to which is attached some value/object. Now whether
this attachment is in the form of storage or binding is IMO not
that important.
In any case, the following doesn't seem to be implementation detail (and
rather a part of the language), but it's not really understandable with a
C++ concept of "variable":
>>>a=3
id(a)
3368152
>>>b=a
id(b)
3368152
>>>b=4
id(b)
3368140

You don't expect the "identity" of the variable b to change with a simple
assignment from a C/C++ point of view.
That depends on what you call the identity. If I had to translate this
into C++ it would be something like:

int *a, *b;

a = MakeInt(3);
b = a;
b = MakeInt(4);

AFAIU, you can wrap these int pointers into some kind of class, so that
they behave as you would expect integers to behave. The id(a) would just
return a, the address of where the integer is stored.

Now whether this is helpfull or not for you in understanding the python
behaviour, I don't know. So if you think this is mixing to many things
I'll drop it.
You also don't expect the "identity"
of a and b to be the same after assigning one to the other. You can create
C++ classes that behave like that (you can implement Python in C++ :),
I'm sorry but IMO you there is no connection between those two.
C doesn't have classes, yet you can still implement Python in C.
but
that doesn't mean that you expect C++ language constructs to behave like
that.
If you have implemented it with that purpose, you do.

--
Antoon Pardon
Jul 30 '06 #59
On 2006-07-30 12:45:50, Antoon Pardon wrote:
>[...] we'd have to use a common definition of "variable". This is a term
so widely used that I'm not sure there is a useful single definition of
it; do you know one?

A name in a scope to which is attached some value/object. Now whether
this attachment is in the form of storage or binding is IMO not
that important.
IMO this is not a useful definition of "variable", as it also includes what
some languages would call a "constant". This definition even includes
preprocessor macros. Once you try to come up with a definition that does
not include these, it probably gets trickier.

>In any case, the following doesn't seem to be implementation detail (and
rather a part of the language), but it's not really understandable with a
C++ concept of "variable":
>>>>a=3
id(a)
3368152
>>>>b=a
id(b)
3368152
>>>>b=4
id(b)
3368140

You don't expect the "identity" of the variable b to change with a simple
assignment from a C/C++ point of view.

That depends on what you call the identity. If I had to translate this
into C++ it would be something like:

int *a, *b;

a = MakeInt(3);
b = a;
b = MakeInt(4);
Yup. But in C/C++ speak, it's more common to call a and b "pointers" rather
than "variables". Of course they are also sometimes called "pointer
variables", but not usually "variables". It's of course not technically
wrong to call the variables, but it's probably rare. And for a reason.

>but that doesn't mean that you expect C++ language constructs to behave
like that.

If you have implemented it with that purpose, you do.
I'm not sure an implementation of C++ that behaves like Python when
handling ints is still C++.
I'm not sure where you're trying to go. I think that most people (and even
Bruno, who argued this issue most strongly) call Python variables
"variables" every now and then, or maybe even usually. But it was helpful
for me to see the difference between Python variables and, say, C
variables. I think this has been a useful discussion in this respect. There
is a difference, and it is important (IMO).

Whether Python variables are in fact "variables" probably depends mostly on
your definition of "variable", and that's IMO a tough one -- a definition
of "variable" that includes all those language elements that various
languages call "variables", and nothing else (that's the tough part).
Whether that definition exists, and whether it includes Python "variables",
remains to be seen :)

Gerhard

Jul 30 '06 #60
"Gerhard Fiedler" <ge*****@gmail.comwrote:

8<---------------------------------

| I'm not sure where you're trying to go. I think that most people (and even
| Bruno, who argued this issue most strongly) call Python variables
| "variables" every now and then, or maybe even usually. But it was helpful
| for me to see the difference between Python variables and, say, C
| variables. I think this has been a useful discussion in this respect. There
| is a difference, and it is important (IMO).
|
| Whether Python variables are in fact "variables" probably depends mostly on
| your definition of "variable", and that's IMO a tough one -- a definition
| of "variable" that includes all those language elements that various
| languages call "variables", and nothing else (that's the tough part).
| Whether that definition exists, and whether it includes Python "variables",
| remains to be seen :)

I am not one for formal definitions but I think something like this:

if s is a python string containing "hello world "
and I can write :

s = s + "some extra stuff"

then for me s is a variable - the fact that in the python implementation there
are two things, namely the original hello world string and the new longer one is
kind of irrelevant - if I try to print s I will get the new longer string, so
from where I stand s is a variable - it has changed over time from having one
"value" to another one...
and that is about the simplest definition you can get - its a symbolic reference
to something that can change over time - and in python it seems to me that every
name is a variable, cos you can tie the name to very different things at
different times:
>>s = "hello world"
print s
hello world
>>s = s + " some more stuff"
print s
hello world some more stuff
>>s = [1,2,3,4,5,6,7,8,9,0]
print s
[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
>>def foo():
print "banana"
>>s = foo
s
<function foo at 0x011DDE30>
>>s()
banana
>>>
s is surely a variable - there is nothing constant over time about it, and from
this point of view its very "mutable" indeed - and what is more - in every case,
after the assignment, unless you have stored a reference with a different name
to them, the old values look from a programmer's point of view as if they have
been "overwritten" - you can't use anything about s to get at them again...

Now there's a thought - an optional slice notation that slices s over time,
so that s{0} is the current s, and s{-1} the previous one, and so on, with
the default being s[{0}] the {0} being optional....

This should be relatively easy to implement at the point of re binding the name
by replacing the pointer (or whatever) to the object with a stack of them. I
think you could only do it in python, but I may be wrong...

Another world first for python? - (TIC)

"Look mommy! - I only use one variable name! "

- Hendrik
Jul 31 '06 #61
Antoon Pardon wrote:
On 2006-07-29, Gerhard Fiedler <ge*****@gmail.comwrote:
>On 2006-07-29 13:47:37, Antoon Pardon wrote:
>>I think the important thing to remember is that the assignment in Python
is a alias maker and not a copy maker. In languages like C, Fortran,
pascal, the assignment makes a copy from what is on the righthand and
stores that in the variable on the lefthand. In languages like Lisp,
Smalltalk and Python, the assignment essentially makes the lefthand
an alias for the righthand.
Yes, I think I got it now :)

It seems that, in essence, Bruno is right in that Python doesn't really
have variables. Everything that seems variable doesn't really change; what
changes is that an element of what seems to change gets rebound.

Aren't you looking too much at implementation details now?

The difference between an alias assignment and a storage assigment
is for instance totaly irrelevant for immutable objects/values like numbers.
# Python
a = 42
b = a
del a

# C
int *a, *b;
a = malloc(sizeof *a);
*a = 42;
b = a;
free(a);
I wouldn't say it's "totally" irrelevant.

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Jul 31 '06 #62
On 2006-07-30, Gerhard Fiedler <ge*****@gmail.comwrote:
On 2006-07-30 12:45:50, Antoon Pardon wrote:
>>[...] we'd have to use a common definition of "variable". This is a term
so widely used that I'm not sure there is a useful single definition of
it; do you know one?

A name in a scope to which is attached some value/object. Now whether
this attachment is in the form of storage or binding is IMO not
that important.

IMO this is not a useful definition of "variable", as it also includes what
some languages would call a "constant". This definition even includes
preprocessor macros. Once you try to come up with a definition that does
not include these, it probably gets trickier.
Sure it is usefull. It may be not 100% formally correct, but often
things that are not 100% formally correct can be better in bringing
an idea accross.
>>[ ... ]

That depends on what you call the identity. If I had to translate this
into C++ it would be something like:

int *a, *b;

a = MakeInt(3);
b = a;
b = MakeInt(4);

Yup. But in C/C++ speak, it's more common to call a and b "pointers" rather
than "variables".
Well in a case like:

int a, b;

You may call a and b "ints" rather than variables, that doesn't stop
them from being variables.
Of course they are also sometimes called "pointer
variables", but not usually "variables". It's of course not technically
wrong to call the variables, but it's probably rare. And for a reason.
Well I don't know about who you talk with, but when I was still using
C and other like languages on a daily basis me and my collegues had
no problem using the word variable, just because the type of the
variable happened to a pointer. AFAIK, the C language reference
doesn't make an exception for calling something a variable, based
on the type (pointer or not) of the variable.
[ ... ]
Whether Python variables are in fact "variables" probably depends mostly on
your definition of "variable", and that's IMO a tough one -- a definition
of "variable" that includes all those language elements that various
languages call "variables", and nothing else (that's the tough part).
Whether that definition exists, and whether it includes Python "variables",
remains to be seen :)
Since Python variables seem to behave essentially the same way as
Lisp and Smalltalk variables and as far as I know "variable" is
the accepted term in those languages for what we are talking about,
I don't see how you can have a definition that includes those
languages but will not include python.

--
Antoon Pardon
Jul 31 '06 #63
Antoon Pardon wrote:
(snip)
Sure it is usefull. It may be not 100% formally correct, but often
things that are not 100% formally correct can be better in bringing
an idea accross.
hear hear...

And yet you still fail to understand why I claimed Python didn't have
variables ? Talk about stubborness :(

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Jul 31 '06 #64
Gerhard Fiedler wrote:
On 2006-07-30 09:54:14, Antoon Pardon wrote:
Aren't you looking too much at implementation details now?

Possibly, but at this point I'm still trying to understand how Python does
these things, and what the useful abstraction level is for me. I also still
have very little experience how I'll put the things we've been discussing
Sorry I've been away from this sub-thread for a while (even though I
kinda started it :P). Yes, I'm also wondering what difference this big
huge argument makes on how I logically follow Python.

Personally, I find this metaphor in "Head First Java" from O'Reilly
Press really helpful for both Python and Java. Before anyone sends me a
letter bomb that says "Python != Java", let me say this: have phun :P.

Anyway, the metaphor goes something like this: variables (for objects,
not primitives) are like cups (just wait, it gets better). You can put
a remote control IN a cup. The remote control controls a "real" object
on the heap (ie, the data for the object is there).

Unfortunately, some of the effect of the metaphor is lost because I
cannot reporduce the very nice illustrations which came in the book :P.

Other than the fact that you declare variables in Java (going down
another letter-bomb-laden slippery slope), which means they stick
around even when they have no "remote controls", I pretty much think of
Python variables the same way: each variable LOGICALLY contains a
reference (ie, without regard to what the mechanics are) to some
amorphous glob of data, sitting on the heap. Therefore, when I do an
assignment, I am simply replacing the reference my variable is holding.
According to the metaphor, we are replacing the remote control our cup
is holding.

If an object is no longer visible (because all the references have
disappeared), then it should get garbage collected eventually. But
until the magical garbage-collecting angle of death makes is way
through the heap, our orphaned objects are PHYSICALLY still there until
they are forcefully evicted from memory. Logically, however, they were
gone as soon as we lost sight of them.

Java aside, My question is this: how will using this metaphor break the
way I logically follow Python?
here into (Python) practice. While not new to programming, I'm new to
Python.
AFAIU, one can also build a C++ class hierarchy that with some small
limitations in used operators, would have semantics very similar to
Python. Would you argue that those using such a C++ class hierarchy would
no longer be using variables in C++?

Probably not. But for me it's mostly about useful terminology, not
necessarily "correct" terminology. In order to talk about correct
terminology, we'd have to use a common definition of "variable". This is a
term so widely used that I'm not sure there is a useful single definition
of it; do you know one?
This is another thing I was thinking the entire time I was reading this
argument, but I didn't want someone to answer me in a condescending
tone on what exactly a variable IS. I guess I should attribute that
quote to Bill Clinton :P.
>
In any case, the following doesn't seem to be implementation detail (and
rather a part of the language), but it's not really understandable with a
C++ concept of "variable":
>a=3
id(a)
3368152
>b=a
id(b)
3368152
>b=4
id(b)
3368140

You don't expect the "identity" of the variable b to change with a simple
assignment from a C/C++ point of view. You also don't expect the "identity"
of a and b to be the same after assigning one to the other. You can create
C++ classes that behave like that (you can implement Python in C++ :), but
that doesn't mean that you expect C++ language constructs to behave like
that.
I'm really not comfortable with C, but I disagree. What would you say
about this program:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define tf(bool) (bool) ? "true" : "false"

const char * greeting = "hello world";

int main() {
/* These mallocs don't really need to be hear for me to make my
point, because as far as I know, what they return is garbage
values anyway :P. I just put them there so my pointers are
pointing to "real objects".*/
char * string = (char *) malloc(sizeof(char)*100);
char * letterBomb = (char *) malloc(sizeof(char)*100);

strcpy(string, greeting);
strcpy(letterBomb, greeting);

printf("are we equal? %s\n", tf(strcmp(string, letterBomb) == 0));
printf("are we IDENTICAL? %s\n", tf(string == letterBomb));

printf("sabotage...\n");
letterBomb = string;
printf("are we identical NOW? %s\n", tf(string==letterBomb));
}
>
Gerhard
Aug 1 '06 #65
On 2006-07-31, Bruno Desthuilliers <on***@xiludom.growrote:
Antoon Pardon wrote:
(snip)
>Sure it is usefull. It may be not 100% formally correct, but often
things that are not 100% formally correct can be better in bringing
an idea accross.

hear hear...

And yet you still fail to understand why I claimed Python didn't have
variables ? Talk about stubborness :(
I don't think it is usefull to claim Python has no variables.

Smalltalk variables behave essentially the same as python
variables and AFAIK never has the term 'variable' been
seen there as an obstacle for understanding how smalltalk
works.

Python objects/classes don't behave exactly the same as
objects/classes in some other languages, are you going to claim
that python has no objects/classes when you want to explain
these difference? What other terminology are you prepared to
throw away because things behave somewhat differently in Python
than they do in some other languages?

IMO you are the one who seem to want 100% formally correctness,
because you wanted to throw away a term because the entity
refered to by it, didn't behave exactly the same as it did
in an other language.

--
Antoon Pardon
Aug 1 '06 #66
On 2006-08-01, danielx <da********@berkeley.eduwrote:
Gerhard Fiedler wrote:
>On 2006-07-30 09:54:14, Antoon Pardon wrote:
Aren't you looking too much at implementation details now?

Possibly, but at this point I'm still trying to understand how Python does
these things, and what the useful abstraction level is for me. I also still
have very little experience how I'll put the things we've been discussing

Sorry I've been away from this sub-thread for a while (even though I
kinda started it :P). Yes, I'm also wondering what difference this big
huge argument makes on how I logically follow Python.

Personally, I find this metaphor in "Head First Java" from O'Reilly
Press really helpful for both Python and Java. Before anyone sends me a
letter bomb that says "Python != Java", let me say this: have phun :P.

Anyway, the metaphor goes something like this: variables (for objects,
not primitives) are like cups (just wait, it gets better). You can put
a remote control IN a cup. The remote control controls a "real" object
on the heap (ie, the data for the object is there).

Unfortunately, some of the effect of the metaphor is lost because I
cannot reporduce the very nice illustrations which came in the book :P.

Other than the fact that you declare variables in Java (going down
another letter-bomb-laden slippery slope), which means they stick
around even when they have no "remote controls", I pretty much think of
Python variables the same way: each variable LOGICALLY contains a
reference (ie, without regard to what the mechanics are) to some
amorphous glob of data, sitting on the heap. Therefore, when I do an
assignment, I am simply replacing the reference my variable is holding.
According to the metaphor, we are replacing the remote control our cup
is holding.

If an object is no longer visible (because all the references have
disappeared), then it should get garbage collected eventually. But
until the magical garbage-collecting angle of death makes is way
through the heap, our orphaned objects are PHYSICALLY still there until
they are forcefully evicted from memory. Logically, however, they were
gone as soon as we lost sight of them.

Java aside, My question is this: how will using this metaphor break the
way I logically follow Python?
I don't think it will cause you problems. The confusion from explaining
Python variables in terms of C-like references comes from the fact that
in Python both assignment and argument passing are reference passings.

In code like the following:

def foo(x):
x = x + 1

a = 0
f(a)
print a

A number of people expect to see 1 printed. They remember that x will
be a reference of a and so expect a to be incremented by 1 after the
call. They forget that the assigment to x will cause x to refer to
a different integer and not cause it to refer to the same "object"
whose value is increased.

An other problem is that people don't realise that an assignment
to a simple identifier in a function, has a declarative effect.
So (unless the identifier was declared global) from the moment
there is some line like: ident = ... in a function, all occurences
of ident in that function will refer to the local variable.

So this works:

def foo():
b = a

a = 1
foo()

This doesn't:

def foo():
b = a
a = 2 * b + 1

a = 1
foo()

Even this doesn't:

def foo():
if False:
a = 1
else:
b = a

a = 1
foo()

Yet seems to work (which I think is an error in the optimisation;
replacing 0 by [], () or None shouldn't make a difference but
it no longer works in those cases):

def foo():
if 0:
a = 1
else:
b = a

a = 1
foo()
--
Antoon Pardon
Aug 1 '06 #67
On 2006-07-31 23:52:07, danielx wrote:
>You don't expect the "identity" of the variable b to change with a
simple assignment from a C/C++ point of view. You also don't expect the
"identity" of a and b to be the same after assigning one to the other.
You can create C++ classes that behave like that (you can implement
Python in C++ :), but that doesn't mean that you expect C++ language
constructs to behave like that.

I'm really not comfortable with C, but I disagree. What would you say
about this program: [...]
"Identity of a variable" is probably even less defined than "variable" :)

What I meant is that in a C/C++ context, I'd fuzzily think about identity
of a variable as its location, the memory address. In this sense, you
change the identity of the content of the pointers, but not the identity of
the pointer variable itself.

After the line "letterBomb = string;", both letterBomb and string still
have each their own "identity" (as in memory address). You copied the
content; which is in this case the address that was stored in string. It's
that level that you never get to in Python (normal Python programming, at
least, I think :).

I think it's probably pretty moot to compare the low level C concept of
variables with the higher level concept of variables that most scripting
languages have. There's a lot of built-in functionality behind the scenes
that C lacks. It of course can be simulated in C with certain assumptions,
but that's not the point.

There's maybe a point in comparing Python variables to C pointers. But it
lacks in the respect that a C programmer is used to modify memory locations
through pointers. A Python programmer isn't used to modify memory locations
in the first place, and simple objects don't get modified at all. There's
no Python equivalent to "int*p=345; *p++;". (There's no need for that in
Python; I'm not saying this shows a superiority of C. It just shows a
different concept of what "variable" means.)

For me, the point of this discussion was that it makes sense to look at it
/differently/. Once you've done that, there's no problem in continuing to
use the (vaguely defined) term "variable".

I admit that for me it was a surprise when I learned that simple numbers
are immutable objects, and I'm sure this wasn't the last time I'll think a
bit about the ramifications of this.

Gerhard

Aug 1 '06 #68
Antoon Pardon wrote:
Even this doesn't:

def foo():
if False:
a = 1
else:
b = a

a = 1
foo()

Yet seems to work (which I think is an error in the optimisation;
What definition of 'seems to work' are you using? It throws an
UnboundLocalError exception so you'll know pretty quickly that something is
wrong.
Aug 1 '06 #69
On 2006-08-01, Dennis Lee Bieber <wl*****@ix.netcom.comwrote:
On Tue, 1 Aug 2006 11:12:31 -0300, Gerhard Fiedler <ge*****@gmail.com>
declaimed the following in comp.lang.python:
>There's maybe a point in comparing Python variables to C pointers. But it
lacks in the respect that a C programmer is used to modify memory locations
through pointers. A Python programmer isn't used to modify memory locations
in the first place, and simple objects don't get modified at all. There's
no Python equivalent to "int*p=345; *p++;". (There's no need for that in
Python; I'm not saying this shows a superiority of C. It just shows a
different concept of what "variable" means.)
Python

c = c + 100

pseudo-C (where I use _p to indicate explicit pointer; and all data
objects are a structure of the form: int ref_count; <object typedata)

scratch_p = malloc()
scratch_p->data = c_p->data + 100
scratch_p->ref_count = 1
c_p->ref_count--
if !c_p->ref_count
free(c_p)
c_p = scratch_p

-------
b = a
is
b = a
b->ref_count++
>For me, the point of this discussion was that it makes sense to look at it
/differently/. Once you've done that, there's no problem in continuing to
use the (vaguely defined) term "variable".

Think the above is "different" enough <G>
The above are implementation details.

Suppose I write a C-interpreter and then would translate a statement
like "c = c + 100" into actions the interpreter would have to take in
order to excute that statement. Something like:

c-addr_p = GetAddress("c");
c-value = *c-addr_p;
sum = c-value + 100;
*c-addr_p = sum;

That look different enough from just "c = c + 100". So maybe C
has no variables either.

--
Antoon Pardon
Aug 1 '06 #70
On 2006-08-02, Dennis Lee Bieber <wl*****@ix.netcom.comwrote:
On 1 Aug 2006 17:44:54 GMT, Antoon Pardon <ap*****@forel.vub.ac.be>
declaimed the following in comp.lang.python:
>Suppose I write a C-interpreter and then would translate a statement
like "c = c + 100" into actions the interpreter would have to take in
order to excute that statement. Something like:

c-addr_p = GetAddress("c");
c-value = *c-addr_p;
sum = c-value + 100;
*c-addr_p = sum;
If this is what your interpreter generates/executes for a C-language
assignment, then the source language is no longer C...
How do you come to that decision?
After all, Python's most common implementation IS in C.

In C, the difference between "c" as a pointer, and "*c" as what it
points to is explicitly exposed to the user... The two views can be
separately manipulated. "c" as a variable can be manipulated -- c++
changes c to "point to" an object (of the type of "c") that is presumed
to follow the existing object -- whether such exists or not.

Python does not expose that to the user... You have a name and you
have an object. The name exists, or it doesn't, independent of the
object. Not in C -- while the object may not exist, the name, to be used
at all, has to exist and has storage space assigned to it; storage the
programmer is able to manipulate without an object.
And how is this all relevant in deciding that the source language for
the above interpreter actions isn't C? What the interpreter does is
the following:

Get the addres of the variable c
Get the value that is at that address.
Add 100 to this value
Store the new value at that address.

Please explain what is wrong in this sequence of actions
for an interpretation of the C statement: "c = c + 100;"

--
Antoon Pardon
Aug 2 '06 #71
On 2006-08-02, Dennis Lee Bieber <wl*****@ix.netcom.comwrote:
On 2 Aug 2006 13:09:26 GMT, Antoon Pardon <ap*****@forel.vub.ac.be>
declaimed the following in comp.lang.python:
>>
And how is this all relevant in deciding that the source language for
the above interpreter actions isn't C? What the interpreter does is
the following:

Get the addres of the variable c
Get the value that is at that address.
Add 100 to this value
Store the new value at that address.

Please explain what is wrong in this sequence of actions
for an interpretation of the C statement: "c = c + 100;"

What interpretation will your hypothetical give for:

c = &c + 1
c++

and

d = *(1000) #I'll concede this one may be a bit invalid
#I don't recall if a cast is needed
Why should I answer this? You stated that my interpreter couldn't
be interpreting the C-language. You did that before you asked these
questions. So it seems your decision for your statement is not
dependend om my answer for these questions. So please clarify
how you came to your decision.

--
Antoon Pardon
Aug 2 '06 #72
On Sun, 30 Jul 2006 11:18:10 -0300
Gerhard Fiedler <ge*****@gmail.comwrote:

#In any case, the following doesn't seem to be implementation detail
#(and rather a part of the language), but it's not really
#understandable with a C++ concept of "variable":
#>
#>a=3
#>id(a)
#3368152
#>b=a
#>id(b)
#3368152
#>b=4
#>id(b)
#3368140

How about that?

int main()
{
int three = 3;
int four = 4;
int *a, *b;
a = &three;
printf("%i %i\n",a,*a);
b = a;
printf("%i %i\n",b,*b);
b = &four;
printf("%i %i\n",b,*b);
return 0;
}

Just in case you don't have C compiler at hand, it prints:

1244896 3
1244896 3
1244888 4

#You don't expect the "identity" of the variable b to change with a simple
#assignment from a C/C++ point of view.

That depends on your definition of "identity", of course.

#You also don't expect the "identity" of a and b to be the same
#after assigning one to the other.

Don't I?

--
Best wishes,
Slawomir Nowaczyk
( Sl***************@cs.lth.se )

You can tell a bigot, but you can't tell him much.

Aug 3 '06 #73
On 2006-08-03 10:57:22, Slawomir Nowaczyk wrote:
#In any case, the following doesn't seem to be implementation detail
#(and rather a part of the language), but it's not really
#understandable with a C++ concept of "variable":
#>
#>a=3
#>id(a)
#3368152
#>b=a
#>id(b)
#3368152
#>b=4
#>id(b)
#3368140

How about that?

int main()
{
int three = 3;
int four = 4;
int *a, *b;
a = &three;
printf("%i %i\n",a,*a);
b = a;
printf("%i %i\n",b,*b);
b = &four;
printf("%i %i\n",b,*b);
return 0;
}

Just in case you don't have C compiler at hand, it prints:
I don't have to :)

But seriously, for my comment this seems off-topic. I did not say that you
can't create Python behavior with C (of course you can, you can do
/everything/ in C :). You can build constructs made up of C variables that
simulate everything that any Python construct does. That's not the point.
The point is how the simple, built-in language variable behaves.
#You don't expect the "identity" of the variable b to change
#with a simple assignment from a C/C++ point of view.

That depends on your definition of "identity", of course.
Right. "Identity" is not defined in C, but most C programmers would
probably take the address of a variable as the closest to a variable's
identity.
#You also don't expect the "identity" of a and b to be the same
#after assigning one to the other.

Don't I?
I don't know. Try replacing your printf statements with something like
"printf("%x %i %i\n",&a,a,*a);" and watch the first column. The address
operator is probably for a C programmer the closest to what the id()
function is to a Python programmer.

Gerhard

Aug 3 '06 #74
Antoon Pardon a écrit :
On 2006-07-31, Bruno Desthuilliers <on***@xiludom.growrote:
>>Antoon Pardon wrote:
(snip)
>>>Sure it is usefull. It may be not 100% formally correct, but often
things that are not 100% formally correct can be better in bringing
an idea accross.

hear hear...

And yet you still fail to understand why I claimed Python didn't have
variables ? Talk about stubborness :(


I don't think it is usefull to claim Python has no variables.
Yes, we know, thanks, good night.
Aug 3 '06 #75
Gerhard Fiedler wrote:
>There's no Python equivalent to "int*p=345; *p++;".
Sure there is:

os.kill(os.getpid(), signal.SIGSEGV)

:)

Aug 5 '06 #76
On Sat, 05 Aug 2006 02:55:03 -0700
Bill Pursell <bi**********@gmail.comwrote:

#Gerhard Fiedler wrote:
# There's no Python equivalent to "int*p=345; *p++;".
#>
#Sure there is:
#>
#os.kill(os.getpid(), signal.SIGSEGV)

LOL... that's a good one :)

--
Best wishes,
Slawomir Nowaczyk
( Sl***************@cs.lth.se )

90% of the time I'm right, so why worry about the other 3%?

Aug 6 '06 #77
I agree with the previous comments that this approach is "bad form".
But if you absolutely *must* modify an enclosing function's variables
with an inner function, all you need to do is remember that a Python
function is an object too, so it can be assigned attributes. ;-)

def outer():
outer.x = 1
print outer.x

def inner():
outer.x = 2

inner()
print outer.x
Josiah Manson wrote:
I found that I was repeating the same couple of lines over and over in
a function and decided to split those lines into a nested function
after copying one too many minor changes all over. The only problem is
that my little helper function doesn't work! It claims that a variable
doesn't exist. If I move the variable declaration, it finds the
variable, but can't change it. Declaring the variable global in the
nested function doesn't work either.

But, changing the variable in the containing scope is the whole purpose
of this helper function.

I'm new to python, so there is probably some solution I haven't
encountered yet. Could you please suggest a nice clean solution? The
offending code is below. Thanks.

def breakLine(s):
"""Break a string into a list of words and symbols.
"""
def addTok():
if len(tok) 0:
ls.append(tok)
tok = ''

ls = []
tok = ''
splitters = '?()&|:~,'
whitespace = ' \t\n\r'

for c in s:
if c in splitters:
addTok()
ls.append(c)
elif c in whitespace:
addTok()
else:
tok = tok + c

addTok()

return ls

#some tests to make sure it works
print breakLine('carolina(Prada):cat(X,Y)')
print breakLine('trouble :bird (X ) &cat ( Y )')
print breakLine('?trouble')
Aug 9 '06 #78
At Wednesday 9/8/2006 16:15, en********@rock.com wrote:
>I agree with the previous comments that this approach is "bad form".
But if you absolutely *must* modify an enclosing function's variables
with an inner function, all you need to do is remember that a Python
function is an object too, so it can be assigned attributes. ;-)

def outer():
outer.x = 1
print outer.x

def inner():
outer.x = 2

inner()
print outer.x
I see two problems:
- Concurrency: two or more threads executing the same function,
writing to this "global"
- Can't be used (easily) on methods

On the original question, I would inherit from list:
def addTok():
if len(tok) 0:
ls.append(tok)
tok = ''

class mylist(list)
def addTok(self, tok):
if len(tok)>0:
self.append(tok)
tok = ''
return tok

ls = mylist()
and use: tok = ls.addTok(tok) whenever the original code says addTok(tok)

Gabriel Genellina
Softlab SRL

__________________________________________________
Preguntá. Respondé. Descubrí.
Todo lo que querías saber, y lo que ni imaginabas,
está en Yahoo! Respuestas (Beta).
¡Probalo ya!
http://www.yahoo.com.ar/respuestas

Aug 10 '06 #79

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

Similar topics

6
by: Andy Baker | last post by:
Hi there, I'm learning Python at the moment and trying to grok the thinking behind it's scoping and nesting rules. I was googling for nested functions and found this Guido quote:...
3
by: jena | last post by:
Hi I have code # BEGIN CODE def test(): def x(): print a a=2 # *** a=1
10
by: Phil Reardon | last post by:
Ive been away from programming for a few years and am having difficulty accessing a function from a math/engineering library that I want to use . I thought that double foo(double); inserted in the...
9
by: Javaman59 | last post by:
Using local declarations within a block often makes code more readable, but is it less efficient? eg... void P() { while (...) { int i = ...; bool b = ...; .... } }
37
by: Tim N. van der Leeuw | last post by:
Hi, The following might be documented somewhere, but it hit me unexpectedly and I couldn't exactly find this in the manual either. Problem is, that I cannot use augmented assignment operators...
7
by: biner.sebastien | last post by:
I have a problem understanding the scope of variable in nested function. I think I got it nailed to the following example copied from Learning Python 2nd edition page 205. Here is the code. def...
4
by: Wolfgang Draxinger | last post by:
If you know languages like Python or D you know, that nested functions can be really handy. Though some compilers (looking at GCC) provide the extension of nested functions, I wonder, how one...
0
by: Maric Michaud | last post by:
Le Tuesday 12 August 2008 11:29:18 Cousson, Benoit, vous avez écrit : This is a language limitation. This is because nested scope is implemented for python function only since 2.3 allow late...
0
by: Cousson, Benoit | last post by:
This is a language limitation. That was my understanding as well, but I think it is a pity to have that limitation. Don't you think that the same improvement that was done for method nested scope...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
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
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
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...

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.