please help explain this result

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Sun Oct 17 07:48:19 EDT 2010


On Sun, 17 Oct 2010 03:58:21 -0700, Yingjie Lan wrote:

> Hi,
> 
> I played with an example related to namespaces/scoping. The result is a
> little confusing:

[snip example of UnboundLocalError]

Python's scoping rules are such that if you assign to a variable inside a 
function, it is treated as a local. In your function, you do this:

def f():
    a = a + 1

Since a is treated as a local, when you enter the function the local a is 
unbound -- it does not have a value. So the right hand side fails, since 
local a does not exist, and you get an UnboundLocalError. You are trying 
to get the value of local "a" when it doesn't have a value.

Why doesn't Python treat the "a" on the right-hand side as global, and 
"a" on the left-hand side as local? That would be confusing, if variables 
had different scope in different places. Python's current scoping rules 
are simple:

(1) If you assign to a variable *anywhere* in the function, it is a local 
*everywhere* in the function.

(2) If you refer to a variable (without assigning to it) in the function, 
and it is not a local, Python searches the nested scopes for a matching 
name. This is necessary so that globals and built-ins will be found, but 
it also works for nested functions and closures. E.g. 

def f(alist):
    n = len(alist)

Obviously alist and n are local variables, but what you might not realise 
is that len() is not known to the compiler, it is just the name of a 
variable which is looked up at runtime.

(3) If you flag a variable with the global statement, then it will be 
treated as global for assignments.

There is no way to have a variable refer to a local in some places of a 
function and a global in other places of the same function. This is by 
design.


[...]
> I suppose I will get 2 ( 'a' is redefined as a local variable, whose
> value is obtained by the value of the global variable 'a' plus 1).

No, Python does not do that.



-- 
Steven



More information about the Python-list mailing list