[Tutor] "local variable 'l1' referenced before assignment"

Martin Walsh mwalsh at groktech.org
Sat Jun 28 11:22:09 CEST 2008


Douglas Drumond wrote:
> 
> In a2() you do l1 += l2, ie, l1 = l1 + l2

A subtle clarification is warranted I think. l1 += l2 is not the same as
l1 = l1 + l2, when l1 and l2 are lists. l1 += l2 is an augmented
assignment statement, and as such will perform the operation in place if
possible, IIUC. Consider the following:

In [1]: l1 = l2 = [1, 2, 3]

In [2]: l1 is l2
Out[2]: True

In [3]: l1 += [4, 5, 6] # in-place

In [4]: l1 is l2
Out[4]: True

In [5]: l1 = l1 + [7, 8, 9] # not

In [6]: l1 is l2
Out[6]: False

Perhaps there is a better reference, but this behavior is discussed
briefly here: http://docs.python.org/ref/augassign.html

> But if you don't have l1 defined yet, you can't add to l2
> It's like:
> def a2():
>         l1 = foo + l2
> 
> 
> UnboundLocalError: local variable 'foo' referenced before assignment
> 
> It's because l1 (and foo at above example) is a local variable.
> a1's l1 is different from a2's l1.
Yes, but as Alan pointed out it's considered local because of the
assignment attempt. Obligatory doc reference:
http://www.python.org/doc/2.4/ref/naming.html

snip = """\
If a name binding operation occurs anywhere within a code block, all
uses of the name within the block are treated as references to the
current block. This can lead to errors when a name is used within a
block before it is bound. This rule is subtle. Python lacks declarations
and allows name binding operations to occur anywhere within a code
block. The local variables of a code block can be determined by scanning
the entire text of the block for name binding operations.
"""

HTH,
Marty


More information about the Tutor mailing list