[Tutor] Question about why a list variable is apparently global.

Steven D'Aprano steve at pearwood.info
Thu Nov 27 11:56:44 CET 2014

On Wed, Nov 26, 2014 at 10:18:55PM -0600, boB Stepp wrote:

> So any variables lower in the program are accessible to those above it?

No, that can't be the explanation. Think of this:

b = a + 1
a = 2

That will fail because when the "b = a + 1" line is executed, a doesn't 
exist yet so there is no way to get a value for it.

In the case of the functions, *defining* the function 

def f(): return g()

is okay because we are just creating the function. But if we tried to 
*call* the function, and execute the code inside it, we would run into a 
NameError exception because g() doesn't exist yet. It is because we 
delay calling the function f() until g() likewise exists that it works 
out without error.

*Inside* a function, code that refers to some name:

    return g()  # refers to name "g"

compiles an instruction to look up the name "g", but the lookup doesn't 
actually take place until you call the function. Therefore the name 
doesn't need to exist when you define the function, only when you call 

*Outside* of a function, code is executed immediately, so the name has 
to exist or there will be an error.

As usual, the interactive interpreter is your friend:

py> b = a + 1  # Oops, "a" doesn't exist yet.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
py> a = 2
py> b = a + 1
py> print b

Compared to:

py> def func():
...     print x
py> func()  # Oops, "x" doesn't exist yet.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in func
NameError: global name 'x' is not defined
py> x = 23
py> func()

> > You only need to declare a global variable inside a function if you are
> > re-assigning a value to it. Hence:
> >
> > a = 1
> > b = 2
> > def test():
> >     global b
> >     b = b + a
> So even though test() has access to a and b, it won't change b when
> called unless b is declared global inside the function?

Python understands that there are two sorts of variables, local 
variables which are local to a function, and global variables which 
exist in a module. (Python 3 adds a third, "nonlocal", but that's a 
story for another day.) It uses a simple rule to decide which is which:

* if you assign to a variable anywhere inside a function, it is 
  treated as a local variable;

* unless you declare it "global";

* otherwise it is global.

So if I neglected to include the global declaration, I would have this:

def test():
    b = b + a

Because there is an assignment to b, it is treated as local, but there 
is no assignment to a. So when you call the function, Python tries to do 

* lookup the value of local variable b
* lookup the value of global variable a
* add them together
* assign the result to local variable b

But notice that the first lookup will fail. b doesn't have a value yet, 
so you will get UnboundLocalError: local variable 'b' referenced before 


More information about the Tutor mailing list