[Tutor] Scoping question

Jeff Shannon jeff@ccvcorp.com
Mon, 09 Sep 2002 10:32:50 -0700


Dana Larose wrote:


> And finally, why does the assignment to a list element execute
> successfully?

Gongalo has already pretty much explained your first question, so I'll tackle
this one.  The difference is that, in the first case, you're re-binding the
name, whereas with the list element, you're mutating an existing object.

When you execute an assignment like "blah = 5", Python creates an integer
object with the value of 5, and binds that to the name blah.  It really
doesn't matter whether blah had already existed or not -- if there was a
previous blah in the same scope, it's pretty much blindly overwritten.  (If
there was a blah in a containing scope, such as the global blah in your
example, then the new local blah masks the global but doesn't overwrite it.)
In either case, the object being pointed to by 'blah' is a *new* object,
regardless of whether blah existed before or not.  Specifically, in the case
of "blah += 1", Python will retrieve the value of blah and add one to it,
creating a new integer object, and then will point blah at that new object.

Things are a bit more complicated in the list case.  There, you are not
re-binding a name.  Let's look at it as "list[0] = list[0] + 1" -- this is
essentially equivalent to your code, but a bit easier to break down into
steps.  Python first finds the value of element 0 of the list, and adds one
to that, creating a new integer object just as before.  However, you then
assign that object to list[0] -- this means that you're not re-binding the
name 'list', or creating a new name.  You're telling Python that the first
slot in this already-existing object is now pointing to something
different... but the object itself still exists, and still has the same name
attached to it.

I find it easier to understand name-binding if you think of names as little
Post-it notes that are attached to objects.  The statement 'blah = blah + 1'
finds the note that says 'blah', creates a new object that's one greater than
the original object, and moves the note to that new object.  The statement
'list[0] = list[0] + 1', on the other hand, finds the note that says 'list',
which is a set of drawers.  It opens the first drawer, adds one to the object
that it finds there, and puts the new object back in that first drawer, but
it does *not* move the sticky note to a new object -- it's still the same set
of drawers.

Hope that this makes things a bit clearer for you...

Jeff Shannon
Technician/Programmer
Credit International