# Beginner's scoping question

Discussion in 'Python' started by Alan Little, Nov 10, 2004.

1. ### Alan LittleGuest

a=1
b=[]
class C():
def __init__(self):
a=2
b.append(3)

c = C()

print b
# [3]

# but ...
print a
# 1

???

Alan Little, Nov 10, 2004

2. ### James StroudGuest

If you make an assignment in a method, the name assumes a local scope in
python. "b" was not assigned so did not assume local scope.

James

On Wednesday 10 November 2004 12:40 pm, Alan Little wrote:
> a=1
> b=[]
> class C():
> def __init__(self):
> a=2
> b.append(3)
>
> c = C()
>
> print b
> # [3]
>
> # but ...
> print a
> # 1
>
> ???

--
James Stroud, Ph.D.
UCLA-DOE Institute for Genomics and Proteomics
611 Charles E. Young Dr. S.
MBI 205, UCLA 951570
Los Angeles CA 90095-1570
http://www.jamesstroud.com/

James Stroud, Nov 10, 2004

3. ### Farshid LashkariGuest

Hi,

You need to declare "a" as global before when you assign something to it
inside a function.

def __init__(self):
global a
a = 2

-Farshid

"Alan Little" <> wrote in message
news:...
> a=1
> b=[]
> class C():
> def __init__(self):
> a=2
> b.append(3)
>
> c = C()
>
> print b
> # [3]
>
> # but ...
> print a
> # 1
>
> ???

Farshid Lashkari, Nov 10, 2004
4. ### Michael LoritschGuest

(Alan Little) wrote in message news:<>...
> 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

Michael Loritsch, Nov 11, 2004
5. ### Ivo WoltringGuest

On 10 Nov 2004 12:40:34 -0800, (Alan Little)
wrote:

>a=1
>b=[]
>class C():

is should be...
class C: # whithout the ()
> def __init__(self):
> a=2
> b.append(3)
>
>c = C()
>
>print b
># [3]
>
># but ...
>print a
># 1
>
>???

a=1
b=[]
class C:
def __init__(self):
global a # !!!!!!!!!!!
a=2
b.append(3)

c = C()

print b
# [3]

# but ...
print a
# 2

a in the class is a local to that class and because it in not assiged
to self.a it is also not normally addressable outside the class
if you want to change the already existing global a you have to
declare it global (see code)

You try to append to a non-existing local variable b.
Python first tries the local() namespace and then the global()
it finds b in the global namespace and appends the value.

cheerz,
Ivo

Ivo Woltring, Nov 11, 2004
6. ### Steven BethardGuest

Premshree Pillai <premshree_python <at> yahoo.co.in> writes:
>
> class C():
>
> is incorrect. Should be
>
> class C:

Or better yet:

class C(object):
...

Unless you're targeting older versions of Python, you probably want to be
creating new-style classes, not old-style classes. Old-style classes are really
only present for backwards-compatibility, and will go away in Python 3000.

Steve

Steven Bethard, Nov 11, 2004
7. ### Alan LittleGuest

Very helpful and informative responses guy. Thanks. I was surprised
that the assignment in the __init__ wouldn't search the enclosing
scope first before creating a new local. But if that's the way it
works, that's the way it works. Now I now.

Alan Little, Nov 12, 2004