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