Strange variable scope... is this right?

Alex Martelli aleaxit at yahoo.com
Thu Jan 18 04:05:14 EST 2001


"Emile van Sebille" <emile at fenx.com> wrote in message
news:945ept$cc0lf$1 at ID-11957.news.dfncis.de...
> Ok.
>
> Now, for the benefit of those of us (or is it just me ;-)
> who thought we were getting the hang of code blocks,
> execution frames and namespaces, it would appear that a for
> loop pushes references to pop before entering the loop, ala:
>
> r = range(5)
> for i in r:
>     if i == 1: del r
>     print i,            #--> 0 1 2 3 4

Somewhat strange way to put it, but, yes: a reference to
r is in existence during the for's execution.  Look at
the for loop just as if it were...:

for i in r:
    <body>

translates to:

__sequence = r
__index = 0
while 1:
    try: i=__sequence[__index]
    except IndexError: break
    __index += 1
    <body>

It's not QUITE like this because of a few nits -- the
reference is not named and you can't get at it inside the
body, and also, there is a test-this-is-a-sequence-and-
not-a-mapping implied in the for statement; but I think
this is a usable model.

So, if <body> does a 'del r', or otherwise affects the
REFERENCE r (as opposed to: the object that r refers to!),
this is no matter.  OK so far?


> However, when del-ing a slice, the presumed pushed
> references are changed:

NO!  The *object* it refers to is being mutated.


> r = range(5)
> for i in r:
>     if i == 1: del r[2:4]
>     print i,            #--> 0 1 4
>
> Therefore, it must be simply a reference to the source
> object (r) that gets pushed.

Yep.  Again, try this 'body' in my above-suggested 'model'
and you'll get the same behavior.


> Assuming that's correct then, is this piece of code with
> annotations the way that it's working?
>
> f = ["row", "cow", "arrow"]
> # create three element list object and bind to 'f'
> for f in f:
>     # save reference to 'f' to iterate over,
>     # re-binding 'f' to each in turn
>     for f in range (len (f)):
>         # save reference to newly created range object of
> len (f)
>         # re-binding 'f' to each in turn
>
> It feels like this is less an issue with namespaces and more
> an issue of how the for loop works.
>
> Am-I-getting-closer-ly y'rs,

Very close, it seems to me.  You do appear to 'get' the
crucial distinction between references and objects, but
there is still a tiny amount of confusion when you talk
about 'references are changed' when meaning OBJECTS are.


Alex






More information about the Python-list mailing list