Beginner's scoping question

A

Alan Little

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

c = C()

print b
# [3]

# but ...
print a
# 1

???
 
J

James Stroud

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

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/
 
F

Farshid Lashkari

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
 
M

Michael Loritsch

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
 
I

Ivo Woltring

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
 
S

Steven Bethard

Premshree Pillai said:
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
 
A

Alan Little

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,019
Latest member
RoxannaSta

Latest Threads

Top