Beginner's scoping question

Michael Loritsch loritsch at gmail.com
Thu Nov 11 02:18:31 EST 2004


contact at alanlittle.org (Alan Little) wrote in message news:<4ef0f3a4.0411101240.21132006 at posting.google.com>...
> a=1
> b=[]
> class C():
>    def __init__(self):
>       a=2
>       b.append(3)
> 
> c = C()
> 
> print b
> # [3]
> 
> # but ...
> print a
> # 1
> 
> ???

The key points are as follows:

The statement 'a=2' simply assigns the 'name' 'a' the value '2' within
the local scope of your __init__ function.

If a name does not exist in the local scope at the time of an
assignment, the name will be created within the local scope, rather
than attempting to look up the name in an enclosing scope.

On the other hand, had there already been an identifier named 'a'
within the __init__ function, the assignment would have simply
assigned the value '2' to the name 'a' regardless of what 'a'
originally referred to.

Now, the statement 'b.append(3)' is not an assignment statement.  For
this reason, there is no attempt to bind an object to the name 'b'. 
In fact, the method 'append' is called, which implies that 'b' is
already bound to an object that implements an 'append' method (if not,
an AttributeError exception will be raised when the object named 'b'
is found, assuming it is found).

Thus, in order to call 'append' on 'b', 'b' must first be found. 
First the local scope is searched for the name 'b' (your __init__
method).  After failing to find it, the enclosing scope is searched,
where the name 'b' was found.

For this reason, the code:

b=[]
class C:
    def __init__(self):
        b=[]
        b.append(3)
 
c = C()
print b

would print out '[]', as I presume you expect.  The key to this
behavior is the assignment statement (i.e. b=[]) within the scope of
the __init__ method.

Regards,

Michael Loritsch



More information about the Python-list mailing list