Variable Scope and Binding
- global a, b, c
- nonlocal a, b
- x = something # binds x
- (x, y) = something # binds x and y
- x += something # binds x. Similarly for all other "op="
- del x # binds x
- for x in something: # binds x
- with something as x: # binds x
- except Exception as ex: # binds ex inside block
Each of the above statements is a binding occurrence -
x become bound to the object denoted by
5. If this statement appears inside a function, then
x will be function-local by default. See the "Syntax" section for a list of binding statements.
Functions skip class scope when looking up names
Classes have a local scope during definition, but functions inside the class do not use that scope when looking up names. Because lambdas are functions, and comprehensions are implemented using function scope, this can lead to some surprising behavior.
Users unfamiliar with how this scope works might expect
e to print
From PEP 227:
Names in class scope are not accessible. Names are resolved in the innermost enclosing function scope. If a class definition occurs in a chain of nested scopes, the resolution process skips class definitions.
From Python's documentation on naming and binding:
The scope of names defined in a class block is limited to the class block; it does not extend to the code blocks of methods – this includes comprehensions and generator expressions since they are implemented using a function scope. This means that the following will fail:
This example uses references from this answer by Martijn Pieters, which contains more in depth analysis of this behavior.
In Python, variables inside functions are considered local if and only if they appear in the left side of an assignment statement, or some other binding occurrence; otherwise such a binding is looked up in enclosing functions, up to the global scope. This is true even if the assignment statement is never executed.
Normally, an assignment inside a scope will shadow any outer variables of the same name:
Declaring a name
global means that, for the rest of the scope, any assignments to the name will happen at the module's top level:
global keyword means that assignments will happen at the module's top level, not at the program's top level. Other modules will still need the usual dotted access to variables within the module.
To summarize: in order to know whether a variable
x is local to a function, you should read the entire function:
- if you've found
global x, then
xis a global variable
- If you've found
nonlocal x, then
xbelongs to an enclosing function, and is neither local nor global
- If you've found
x = 5or
for x in range(3)or some other binding, then
xis a local variable
xbelongs to some enclosing scope (function scope, global scope, or builtins)
If a name is bound inside a function, it is by default accessible only within the function:
Control flow constructs have no impact on the scope (with the exception of
except), but accessing variable that was not assigned yet is an error:
Common binding operations are assignments,
for loops, and augmented assignments such as
a += 5
Local vs Global Scope
What are local and global scope?
All Python variabes which are accessible at some point in code are either in local scope or in global scope.
The explanation is that local scope includes all variables defined in the current function and global scope includes variabled defined outside of the current function.
One can inspect which variables are in which scope. Built-in functions
globals() return the whole scopes as dictionaries.
What happens with name clashes?
To modify a global variable, use keyword
The scope is defined for the whole body of the function!
What it means is that a variable will never be global for a half of the function and local afterwards, or vice-versa.
Likewise, the oposite:
Functions within functions
There may be many levels of functions nested within functions, but within any one function there is only one local scope for that function and the global scope. There are no intermediate scopes.
nonlocal (Python 3 only)
Both these keywords are used to gain write access to variables which are not local to the current functions.
global keyword declares that a name should be treated as a global variable.
On the other hand,
nonlocal (see Nonlocal Variables ), available in Python 3, takes a local variable from an enclosing scope into the local scope of current function.
From the Python documentation on
The nonlocal statement causes the listed identifiers to refer to previously bound variables in the nearest enclosing scope excluding globals.
Python 3 added a new keyword called nonlocal. The nonlocal keyword adds a scope override to the inner scope. You can read all about it in PEP 3104. This is best illustrated with a couple of code examples. One of the most common examples is to create function that can increment:
If you try running this code, you will receive an UnboundLocalError because the num variable is referenced before it is assigned in the innermost function. Let's add nonlocal to the mix:
nonlocal will allow you to assign to variables in an outer scope, but not a global scope. So you can't use
nonlocal in our
counter function because then it would try to assign to a global scope. Give it a try and you will quickly get a
SyntaxError. Instead you must use
nonlocal in a nested function.
(Note that the functionality presented here is better implemented using generators.)
The del command
This command has several related yet distinct forms.
v is a variable, the command
del v removes the variable from its scope. For example:
delis a binding occurence, which means that unless explicitly stated otherwise (using
del vwill make
vlocal to the current scope. If you intend to delete
vin an outer scope, use
global vin the same scope of the
In all the following, the intention of a command is a default behavior but is not enforced by the language. A class might be written in a way that invalidates this intention.
This command triggers a call to
The intention is to make the attribute
name unavailable. For example:
This command triggers a call to
The intention is that
item will not belong in the mapping implemented by the object
v. For example:
This actually calls
The intention is similar to the one described above, but with slices - ranges of items instead of a single item. For example:
See also Garbage Collection#The del command.