Namespaces in Python
A namespace is a mapping from names to objects. Most namespaces are currently implemented as Python dictionaries.
Namespaces provide a way to avoid naming conflicts in a project. Each namespace is independent, meaning no name within a namespace can be duplicated, but names in different namespaces can be identical without causing conflicts.
Let’s use a computer system example: a folder can contain multiple subfolders, and each subfolder cannot have files with the same name. However, files in different folders can have the same name.
Types of Namespaces
There are generally three types of namespaces:
Built-in Names: These are names built into Python, such as function names (
abs
,char
) and exception names (BaseException
,Exception
).Global Names: Names defined at the module level, including functions, classes, and variables.
Local Names: Names defined within functions, including parameters and locally defined variables.
Namespace Lookup Order
When Python looks for a variable (e.g., runoob
), it searches in the following order:
Local namespace → Global namespace → Built-in namespace.
If the variable is not found, Python will raise a NameError
:
NameError: name 'runoob' is not defined
Namespace Lifetime
The lifetime of a namespace is determined by the scope of its objects. Once the object is done executing, the namespace is no longer accessible.
Example:
# var1 is a global name var1 = 5 def some_func(): # var2 is a local name var2 = 6 def some_inner_func(): # var3 is a nested local name var3 = 7
Scope in Python
A scope is a textual region of a Python program where a namespace is directly accessible. This means an unqualified reference to a name will try to find the name in the current namespace.
In Python, variables are not accessible everywhere in the code. The location where a variable is assigned determines its scope. There are four types of scopes in Python:
L (Local): Innermost scope, containing local variables (e.g., inside a function).
E (Enclosing): The scope of any enclosing function, excluding global scope.
G (Global): The outermost scope, usually the module-level scope.
B (Built-in): Contains built-in functions and keywords.
Scope lookup order: Local → Enclosing → Global → Built-in.
g_count = 0 # Global scope def outer(): o_count = 1 # Enclosing scope def inner(): i_count = 2 # Local scope
Global and Nonlocal Keywords
When modifying variables from an outer scope within a function, the global
or nonlocal
keyword must be used.
Example: Using global
num = 1 def fun1(): global num print(num) # Outputs: 1 num = 123 print(num) # Outputs: 123 fun1() print(num) # Outputs: 123
Example: Using nonlocal
def outer(): num = 10 def inner(): nonlocal num num = 100 print(num) # Outputs: 100 inner() print(num) # Outputs: 100 outer()
Example of a Scope Error
a = 10 def test(): a = a + 1 print(a) test()
This results in an error:
UnboundLocalError: local variable 'a' referenced before assignment
Variable Scope Modification Example:
Using global
:
a = 10 def test(): global a a = a + 1 print(a) test() # Outputs: 11
Passing through function parameters:
a = 10 def test(a): a = a + 1 print(a) test(a) # Outputs: 11