lists: += vs. .append() & oddness with scope of variables

  • Thread starter Sandro Dentella
  • Start date
S

Sandro Dentella

I'd like to understand why += operator raises an error while .append() does
not. My wild guess is the parses treats them differently but I cannot
understand why this depends on scope of the variables (global or class
variables):


a = [0]

class foo(object):

def __init__(self):
print "a: ", a
# += does not work if 'a' is global
#a += [1]
a.append(2)
print "a= ", a

class bar(object):

b = [0]

def __init__(self):
print "b: ", self.b
# += *does* work if 'a' is class var
self.b += [1]
self.b.append(2)
print "b= ", self.b


if __name__ == '__main__':
x = foo()
y = bar()

a: [0]
a= [0, 2]
b: [0]
b= [0, 1, 2]

uncommenting 'a += [1]' would raise:

a:
Traceback (most recent call last):
File "c1.py", line 26, in ?
x = foo()
File "c1.py", line 7, in __init__
print "a: ", a
UnboundLocalError: local variable 'a' referenced before assignment

TIA
sandro
*:)
 
F

Felipe Almeida Lessa

Em Dom, 2006-03-05 às 11:49 +0000, Sandro Dentella escreveu:
class foo(object):

def __init__(self):
print "a: ", a
# += does not work if 'a' is global
#a += [1]
a.append(2)
print "a= ", a

Try with:
a = [0]

class foo(object):
def __init__(self):
global a
print "a: ", a
a += [1]
a.append(2)
print "a= ", a

foo()

--
"Quem excele em empregar a força militar subjulga os exércitos dos
outros povos sem travar batalha, toma cidades fortificadas dos outros
povos sem as atacar e destrói os estados dos outros povos sem lutas
prolongadas. Deve lutar sob o Céu com o propósito primordial da
'preservação'. Desse modo suas armas não se embotarão, e os ganhos
poderão ser preservados. Essa é a estratégia para planejar ofensivas."

-- Sun Tzu, em "A arte da guerra"
 
D

Duncan Booth

Sandro said:
I'd like to understand why += operator raises an error while .append()
does not. My wild guess is the parses treats them differently but I
cannot understand why this depends on scope of the variables (global
or class variables):


a = [0]

class foo(object):

def __init__(self):
print "a: ", a
# += does not work if 'a' is global
#a += [1]
a.append(2)
print "a= ", a

Any assignment to a variable within a function means that the name to which
you are assigning is regarded as a local variable (unless you use the
'global' statement to override that). += is a form of assignment, calling
the append method is not an assignment.

The solution here is simply to use 'global a' to tell the compiler that you
meant to assign the the global variable rather than creating a new local
variable.
 
S

Scott David Daniels

Duncan said:
....

Any assignment to a variable within a function means that the name to which
you are assigning is regarded as a local variable (unless you use the
'global' statement to override that). += is a form of assignment, calling
the append method is not an assignment.

The solution here is simply to use 'global a' to tell the compiler that you
meant to assign the the global variable rather than creating a new local
variable.

As Duncan knows but forgot to mention, eric.append(spam) doesn't write
the variable eric, it simply manipulates the object that eric names.
 
T

Terry Reedy

Sandro Dentella said:
I'd like to understand why += operator raises an error while .append()
does
not.

Your mistake is thinking of '+=' as an operator. In Python terms it is
not, any more than '=' is. In Python, neither 'a=b' nor 'a+=b' is an
expression. Both symbols are statement symbols that define assigment
statements (augmented in the former case). "a.append(b)" is an expression
with side effects used as a statement.
Traceback (most recent call last):
File "c1.py", line 26, in ?
x = foo()
File "c1.py", line 7, in __init__
print "a: ", a
UnboundLocalError: local variable 'a' referenced before assignment

This is the clue that you did not get. It tells you that the parser thinks
'a' is local, which means you rebound the name 'a' *somewhere* in the
function, even if not as obviously as a simple assignment "a = whatever".
It turns out that augmented assignment statements are assignments
statements ;-).

Terry Jan Reedy
 

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,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top