Python has two scopes (which is really three) plus special rules for nested local scopes. The two scopes are global, for the module-level names, and local, for anything in a function. Anything you assign to in a function is automatically local, unless you declare it otherwise with the global
statement in that function. If you use a name that is not assigned to anywhere in the function, it's not a local name; Python will (lexically) search nesting functions to see if they have that name as a local name. If there are no nesting functions or the name isn't local in any of them, the name is assumed to be global.
(The global namespace is special as well, because it's actually both the module global namespace and the builtin namespace, which is tucked away in the builtins
or __builtins__
module.)
In your case, you have three x
variables: one in the module (global) scope, one in the counter
function and one in the temp
function -- because +=
is also an assignment statement. Because the mere fact of assigning to the name makes it local to the function, your +=
statement will try to use a local variable that hasn't been assigned to yet, and that will raise an UnboundLocalError.
If you intended for all three of these x
references to refer to the global variable, you'd need to do global x
in both the counter
and the temp
function. In Python 3.x (but not 2.x), there is a nonlocal
declaration quite like global
that you can use to make temp
assign to the variable in counter
, but leave the global x
alone.