Variables
Variables in Python are automatically declared by assignment. Variables are always references to objects, and are never typed. Variables exist only in the current scope or global scope. When they go out of scope, the variables are destroyed, but the objects to which they refer are not (unless the number of references to the object drops to zero).
Scope is delineated by function and class blocks. Both functions and their scopes can be nested. So therefore
def foo():
def bar():
x = 5 # x is now in scope
return x + y # y is defined in the enclosing scope later
y = 10
return bar() # now that y is defined, bar's scope includes y
Now when this code is tested,
>>> foo()
15
>>> bar()
Traceback (most recent call last):
File "<pyshell#26>", line 1, in -toplevel-
bar()
NameError: name 'bar' is not defined
The name 'bar' is not found because a higher scope does not have access to the names lower in the hierarchy.
It is a common pitfall to fail to lookup an attribute (such as a method) of an object (such as a container) referenced by a variable before the variable is assigned the object. In its most common form:
>>> for x in range(10):
y.append(x) # append is an attribute of lists
Traceback (most recent call last):
File "<pyshell#46>", line 2, in -toplevel-
y.append(x)
NameError: name 'y' is not defined
Here, to correct this problem, one must add y = [] before the for loop.
A loop does not create its own scope:
for x in [1, 2, 3]:
inner = x
print inner # 3 rather than an error
Keyword global
Global variables of a Python module are read-accessible from functions in that module. In fact, if they are mutable, they can be also modified via method call. However, they cannot modified via a plain assignment unless declared global in the function.
An example to clarify:
count1 = 1
count2 = 1
list1 = []
list2 = []
def test1():
print count1 # Read access is unproblematic, referring to the global
def test2():
try:
print count1 # This print would be unproblematic, but it throws an error ...
count1 += 1 # ... since count1 += 1 causes count1 to be local.
except UnboundLocalError as error:
print "Error caught:", error
def test3():
list1 = [2] # No outside effect; this rebinds list1 to be a local variable
def test4():
global count2, list2
print count1 # Read access is unproblematic, referring to the global
count2 += 1 # We can modify count2 via assignment
list1.append(1) # Impacts the global list1 even without global declaration
list2 = [2] # Impacts the global list2
test1()
test2()
test3()
test4()
print "count1:", count1 # 1
print "count2:", count2 # 2
print "list1:", list1 # [1]
print "list2:", list2 # [2]
Links:
- 6.13. The global statement, docs.python.org
- What are the rules for local and global variables in Python? in Programming FAQ, docs.python.org
Keyword nonlocal
Keyword nonlocal, available since Python 3.0, is an analogue of global for nested scopes. It enables a nested function of assign-modify a variable that is local to the outer function.
An example:
# Requires Python 3
def outer():
outerint = 0
outerint2 = 10
def inner():
nonlocal outerint
outerint = 1 # Impacts outer's outerint only because of the nonlocal declaration
outerint2 = 1 # No impact
inner()
print(outerint)
print(outerint2)
outer()
Simulation of nonlocal in Python 2 via a mutable object:
def outer():
outerint = [1] # Technique 1: Store int in a list
class outerNL: pass # Technique 2: Store int in a class
outerNL.outerint2 = 11
def inner():
outerint[0] = 2 # List members can be modified
outerNL.outerint2 = 12 # Class members can be modified
inner()
print outerint[0]
print outerNL.outerint2
outer()
Links:
- 7.13. The nonlocal statement, docs.python.org
globals and locals
To find out which variables exist in the global and local scopes, you can use locals() and globals() functions, which return dictionaries:
int1 = 1
def test1():
int1 = 2
globals()["int1"] = 3 # Write access seems possible
print locals()["int1"] # 2
test1()
print int1 # 3
Write access to locals() dictionary is discouraged by the Python documentation.
Links:
- 2. Built-in Functions # globals, docs.python.org
- 2. Built-in Functions # locals, docs.python.org
External links
- 4. Execution model, docs.python.org
- 7.13. The nonlocal statement, docs.python.org
- PEP 3104 -- Access to Names in Outer Scopes, python.org