simple question

Jeff Shannon jeff at ccvcorp.com
Thu Aug 16 18:30:09 EDT 2001


Joonas Paalasmaa wrote:

> Bignose3 wrote:
> >
> > An explanation would be great to.  Not a complex program but you have
> > to start somewhere:)
>
> Add the global statement to __init__ achieve the result simply.
>

[trimming code examples]

And the explanation has to do with Python's scoping and name-binding rules.

Python has several levels of scoping--local, global, and builtin.  When you
refer to a variable, the interpreter searches the local scope first.  If it
fails to find it there, it searches the global scope, and then the builtin
scope (and raises a NameException if it fails to find it at all).  You have
your NextID in the global scope.  When you, in __init__(), assign to
self.ID, there is no NextID in the local scope, so Python then checks the
global scope, where it finds NextID, so everything is dandy there.

However, whenever you assign to a variable name, Python always assumes that
that name should go into the local scope, unless specifically told
otherwise.  In the assignment line (NextID = NextID + 1), the right hand
side is created just as you'd expect, by looking up the (global) NextID and
adding one to it.  That result is then assigned to the name NextID --
*but*, since assignment defaults to local scope, you are creating a *new*,
local NextID.  If you used NextID again just after this, you'd be getting
the local version, not the global version.  However, you don't, and the
function exits, thus destroying the local scope and the local version of
NextID.  When you create your next object, you look up the global NextID
again--but that was never changed, so you end up with the same ID for each
object.

When you explicitly declare NextID to be global from within __init__(), as
suggested by Joonas, then Python knows that you do *not* want to create a
local variable of that name, and the assignment line *does* modify the
global version of NextID, so you get properly increasing ID numbers.

By the way, as of v2.0, Python has augmented assignment operators, so you
can write the assignment line as NextID += 1.

Jeff Shannon
Technician/Programmer
Credit International








More information about the Python-list mailing list