scope of variables

bruno at modulix onurb at xiludom.gro
Thu May 4 12:19:45 CEST 2006


Gary Wessle wrote:
> Ryan Forsythe <ryan at cs.uoregon.edu> writes:
> 
> 
>>Gary Wessle wrote:
>>
>>>the example was an in-accuretlly representation of a the problem I am
>>>having. my apologies.
>>>
(snip)
> I finally was able to duplicate the error with a through away code
> as follows, 
> 
> ****************************************************************
> acc = [1,2,3]
> 
> def a():
>     b = [4, 5, 6]
>     acc = acc + b
>     print len(acc)
> 
> a()
> 
> **************** error ****************
> Traceback (most recent call last):
>   File "a.py", line 12, in ?
>     a()
>   File "a.py", line 9, in a
>     acc = acc + b
> UnboundLocalError: local variable 'acc' referenced before assignment

This is a FAQ:
http://www.python.org/doc/faq/programming/#what-are-the-rules-for-local-and-global-variables-in-python

For short: if a name is 'assigned' (in Python, the correct term is
'bound') in the local scope, it'll be considered a local name. If it's
*only* accessed, it'll be looked up in the enclosing namespace - here
the so-called 'global' (which means: 'module') namespace.

The dirty solution is to declare 'acc' as global in the function:
def a():
    b = [4, 5, 6]
    global acc
    acc = acc + b
    print len(acc)

but this is really BadCode(tm). As a general rule, functions should not
silently modify or rebind global variables - this leads to maintenance
nightmares. In this case, you should manage to either 1/ pass acc as a
param to a(), or 2/ have a() return the sequence to be added to acc:

# 1
acc = [1,2,3]
def a(alist):
  alist.extend([4, 5, 6])
  return alist

acc = a(acc)
print acc, len(acc)

# 2
acc = [1,2,3]
def a():
  return [4, 5, 6]

acc.extend(a())
print acc, len(acc)


The Right Thing(tm) to do of course depends on the real code, so it may
be yet another solution, but it's impossible to decide with dummy code...

-- 
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'onurb at xiludom.gro'.split('@')])"



More information about the Python-list mailing list