= "global"
var
def func():
print("inside func call var = " + var)
func()
print("in global scope var = " + var)
>>> inside func call var = global
>>> in global scope var = global
A namespace is a mapping from names (variables) to object references. When python interpreter reads the code it needs to lookup objects referenced by variable names used. As discussed earlier, objects are stored on computer RAM and can be accessed using object’s memory address. Namespaces help find and access the associated objects using variable names. Technically, in Python, they are dictionaries that store this mapping.
A scope is a textual region of the code which has its own separate namespace. This helps isolate and manage different variable names and objects used in different blocks of code. Many languages do this by keeping track of namespace for all blocks, e.g. control flow blocks (if
, for
, …). Python restricts this to just function and class/instance object blocks. Control flow blocks like if
, for
etc. do not have their local scopes.
There is a lot of ambiguity in terminology related to this. For example environments and frames are used interchangeably to refer to the concept of namespace and scope discussed here. To avoid this issue, try to understand the underlying concepts and the issue with the terminology will not impact.
Python tutor is an excellent resource to do small experiments to understand the rules explained in this section. A good starting point would be to try the examples provided in the tool.
Below are the scopes in the order they are searched
return
or errorScope of variable names used in a function definition
global
: variable is looked up in global name space skipping enclosing functions namespacesnonlocal
: variable is looked up only in the enclosing function scopeOn end of function execution the function scope’s namespace is deleted
When cross referencing functions from other modules
global
= "global"
var
def func():
print("inside func call var = " + var)
func()
print("in global scope var = " + var)
>>> inside func call var = global
>>> in global scope var = global
Since var
is not assigned, only referenced in the func
definition, it is searched in local namespace then in global namespace. Since global namespace has var
defined its value is used.
local
= "global"
var
def func():
= "local"
var print("inside func call var = " + var)
func()
print("in global scope var = " + var)
>>> inside func call var = local
>>> in global scope var = global
Since var
is assigned in func
definition, it is tagged to local scope. Therefore there are 2 different var
names in 2 different namespaces, global namespace and func’s namespace created during its call.
global
with nested scopes= "global"
var
def outer_func():
def inner_func():
print("inside inner_func call var = " + var)
inner_func()
outer_func()
print("in global scope var = " + var)
>>> inside inner_func call var = global
>>> in global scope var = global
nonlocal
= "global"
var
def outer_func():
= "nonlocal"
var
def inner_func():
nonlocal var
print("inside inner_func call var = " + var)
inner_func()print("inside outer_func call var = " + var)
outer_func()
print("in global scope var = " + var)
>>> inside inner_func call var = nonlocal
>>> inside outer_func call var = nonlocal
>>> in global scope var = global
global
in nested scopes= "global"
var
def outer_func():
= "nonlocal"
var
def inner_func():
global var
print("inside inner_func call var = " + var)
inner_func()print("inside outer_func call var = " + var)
outer_func()
print("in global scope var = " + var)
>>> inside inner_func call var = global
>>> inside outer_func call var = nonlocal
>>> in global scope var = global
Namespaces and scopes are always getting used by the interpreter while running any piece of code. In the beginning, being aware of the rules is sufficient for regular use in avoiding and resolving errors and understanding code. It is advisable to keep the use of namespaces simple.
For example while using functions, do not try to use namespace and scope rules to create complex solutions if the problem can be solved using without them.
There are many program design techniques implemented using the rules of namespaces and scopes. For example factory and decorator functions are created using these rules.