0% found this document useful (0 votes)
0 views

Python Namespaces

The document provides an in-depth exploration of Python namespaces, detailing their types, such as built-in, global, local, and enclosing namespaces, and their significance in preventing naming conflicts and managing variable scope. It includes practical examples demonstrating the use of namespaces in functions and classes, as well as advanced concepts like closures and type annotations. Additionally, it outlines best practices for working with namespaces and name resolution rules in Python.

Uploaded by

Shahwali
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
0 views

Python Namespaces

The document provides an in-depth exploration of Python namespaces, detailing their types, such as built-in, global, local, and enclosing namespaces, and their significance in preventing naming conflicts and managing variable scope. It includes practical examples demonstrating the use of namespaces in functions and classes, as well as advanced concepts like closures and type annotations. Additionally, it outlines best practices for working with namespaces and name resolution rules in Python.

Uploaded by

Shahwali
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 20

Python

Understanding Python
Namespaces
A Deep Dive into Python’s Name Resolution
May 2, 2025

Source Code
PYTHON NAMESPACES

1. Understanding Python Namespaces


In Python, a namespace is a container that holds a mapping of names to objects.
Think of it as a dictionary where variable names are the keys and the objects
they refer to are the values. Understanding namespaces is crucial because they:

• Prevent naming conflicts by organizing names into hierarchical spaces


• Define the scope and lifetime of variables
• Help manage the visibility and accessibility of variables

2. Types of Namespaces
Python has several types of namespaces with different lifetimes:

• Built-in Namespace: Contains built-in functions and exceptions


• Global Namespace: Module-level variables and functions
• Local Namespace: Names inside functions
• Enclosing Namespace: Names in outer functions (for nested functions)

Let’s explore each type with practical examples:

2.1. Basic Namespace Example


How to Run:

Alejandro Sánchez Yalí


Software Developer | AI & Blockchain Enthusiast
€ www.asanchezyali.com
PYTHON NAMESPACES

• Save the code as 01_basic_namespaces.py


• Run: python3 01_basic_namespaces.py

1 # --- 01_basic_namespaces.py ---


2 """
3 Basic Namespaces in Python
4
5 This file demonstrates the fundamental concept of
namespaces in Python.
6 A namespace is a mapping from names to objects.
7 """
8
9 # The built-in namespace contains functions like print,
len, etc.
10 print("Built-in namespace example:")
11 print(f"Type of len function: {type(len)}")
12 print(f"ID of len function: {id(len)}")
13
14 # The global namespace of a module
15 x = 10
16 y = "hello"

Alejandro Sánchez Yalí


Software Developer | AI & Blockchain Enthusiast
€ www.asanchezyali.com
PYTHON NAMESPACES

17
18 print("\nGlobal namespace example:")
19 print(f"x = {x}, type: {type(x)}, id: {id(x)}")
20 print(f"y = {y}, type: {type(y)}, id: {id(y)}")
21
22 # Local namespace in a function with proper global
variable handling
23 def example_function():
24 # Declare x as global before using it
25 global x
26 z = 20 # Local variable
27 print("\nLocal namespace inside function:")
28 print(f"z = {z}, type: {type(z)}, id: {id(z)}")
29
30 # Now we can safely access and modify the global x
31 print(f"x from global namespace: {x}")
32 x = 30 # This modifies the global x
33 print(f"Modified global x: {x}")
34
35 # Call the function
36 print("\nBefore function call:")
37 print(f"Global x is: {x}")

Alejandro Sánchez Yalí


Software Developer | AI & Blockchain Enthusiast
€ www.asanchezyali.com
PYTHON NAMESPACES

38
39 example_function()
40
41 print("\nAfter function call:")
42 print(f"Global x is now: {x}") # Will show the modified
value

Key points about this example:


• Built-in functions like len live in the built-in namespace
• Variables defined at module level (x and y) are in the global namespace
• Variables defined inside functions (z) are in the local namespace
• The global keyword allows modifying global variables from inside func-
tions

2.2. Nested Scopes and the nonlocal Keyword


Let’s explore how Python handles nested function scopes and the usage of the
nonlocal keyword:
How to Run:
• Save the code as 02_nested_scopes.py
• Run: python3 02_nested_scopes.py

Alejandro Sánchez Yalí


Software Developer | AI & Blockchain Enthusiast
€ www.asanchezyali.com
PYTHON NAMESPACES

1 # --- 02_nested_scopes.py ---


2 """
3 Nested Scopes and the nonlocal Keyword
4
5 This file demonstrates how Python handles nested function
scopes
6 and the usage of the ’nonlocal’ keyword for modifying
variables
7 in outer (but not global) scopes.
8 """
9
10 def scope_test():
11 def do_local():
12 spam = "local spam" # Creates a new local variable
13
14 def do_nonlocal():
15 nonlocal spam # Refers to spam in scope_test
16 spam = "nonlocal spam"
17
18 def do_global():

Alejandro Sánchez Yalí


Software Developer | AI & Blockchain Enthusiast
€ www.asanchezyali.com
PYTHON NAMESPACES

19 global spam # Refers to global spam


20 spam = "global spam"
21
22 # Initialize spam in scope_test’s scope
23 spam = "test spam"
24 print("Initial value:", spam)
25
26 do_local()
27 print("After local assignment:", spam)
28
29 do_nonlocal()
30 print("After nonlocal assignment:", spam)
31
32 do_global()
33 print("After global assignment:", spam)
34
35 print("Starting scope test\n")
36 scope_test()
37 print("\nIn global scope:", spam) # Will print the global
spam value

This example demonstrates:


• Local assignments do not affect variables in outer scopes

Alejandro Sánchez Yalí


Software Developer | AI & Blockchain Enthusiast
€ www.asanchezyali.com
PYTHON NAMESPACES

• nonlocal allows modifying variables in the nearest enclosing scope


• global allows modifying variables in the global scope
• Each function has its own local namespace

2.3. Class and Instance Namespaces


Python also has special namespaces for classes and instances. Let’s explore how
they work:
How to Run:
• Save the code as 03_class_namespaces.py
• Run: python3 03_class_namespaces.py

1 # --- 03_class_namespaces.py ---


2 """
3 Class and Instance Namespaces
4
5 This file demonstrates how Python handles namespaces in
classes,
6 showing the difference between class variables (shared by
all instances)
7 and instance variables (unique to each instance).

Alejandro Sánchez Yalí


Software Developer | AI & Blockchain Enthusiast
€ www.asanchezyali.com
PYTHON NAMESPACES

8 """
9
10 class Dog:
11 # Class variable - shared by all instances
12 species = "Canis familiaris"
13
14 # Class variable containing a mutable object (for
demonstration)
15 tricks = [] # Shared by all dogs!
16
17 def __init__(self, name):
18 # Instance variables - unique to each instance
19 self.name = name
20 self.individual_tricks = [] # Better - each dog
has its own list
21
22 def add_shared_trick(self, trick):
23 # Modifies the class variable (affects all dogs)
24 Dog.tricks.append(trick)
25
26 def add_individual_trick(self, trick):
27 # Modifies the instance variable (affects only

Alejandro Sánchez Yalí


Software Developer | AI & Blockchain Enthusiast
€ www.asanchezyali.com
PYTHON NAMESPACES

this dog)
28 self.individual_tricks.append(trick)
29
30 # Create two dogs
31 print("Creating two dogs...\n")
32 fido = Dog("Fido")
33 buddy = Dog("Buddy")
34
35 # Demonstrate class variable sharing
36 print("Class variable demonstration:")
37 print(f"Fido’s species: {fido.species}")
38 print(f"Buddy’s species: {buddy.species}")
39
40 # Change the class variable
41 Dog.species = "Canis lupus familiaris"
42 print("\nAfter changing class variable:")
43 print(f"Fido’s species: {fido.species}")
44 print(f"Buddy’s species: {buddy.species}")
45
46 # Demonstrate instance variable independence
47 print("\nInstance variable demonstration:")
48 print(f"Fido’s name: {fido.name}")

Alejandro Sánchez Yalí


Software Developer | AI & Blockchain Enthusiast
€ www.asanchezyali.com
PYTHON NAMESPACES

49 print(f"Buddy’s name: {buddy.name}")


50
51 # Demonstrate the difference with mutable objects
52 print("\nShared tricks list (class variable):")
53 fido.add_shared_trick("roll over")
54 print(f"Fido’s tricks: {Dog.tricks}")
55 print(f"Buddy’s tricks: {buddy.tricks} # Same list!")
56
57 print("\nIndividual tricks lists (instance variables):")
58 fido.add_individual_trick("play dead")
59 buddy.add_individual_trick("fetch")
60 print(f"Fido’s individual tricks:
{fido.individual_tricks}")
61 print(f"Buddy’s individual tricks:
{buddy.individual_tricks}")
62
63 # Demonstrate attribute lookup order
64 print("\nAttribute lookup demonstration:")
65 buddy.species = "Changed for buddy" # Creates a new
instance variable
66 print(f"Fido’s species (from class): {fido.species}")
67 print(f"Buddy’s species (from instance): {buddy.species}")

Alejandro Sánchez Yalí


Software Developer | AI & Blockchain Enthusiast
€ www.asanchezyali.com
PYTHON NAMESPACES

68 print(f"Class species attribute: {Dog.species}")

Key points about class and instance namespaces:


• Class variables are shared among all instances
• Instance variables are unique to each instance
• Be cautious with mutable class variables
• Python looks up attributes first in the instance namespace, then in the class
namespace

3. Advanced Namespace Concepts: Closures and An-


notations
Python’s namespace system becomes even more powerful when working with
closures and type annotations. These advanced features demonstrate the flex-
ibility and sophistication of Python’s scoping rules.

3.1. Function Closures and Free Variables


A closure occurs when a nested function references variables from its enclosing
scope. The inner function "closes over" the variables it needs, preserving them
even after the outer function returns.
How to Run:
• Save the code as 04_closures_annotations.py

Alejandro Sánchez Yalí


Software Developer | AI & Blockchain Enthusiast
€ www.asanchezyali.com
PYTHON NAMESPACES

• Run: python3 04_closures_annotations.py

1 # --- 04_closures_annotations.py ---


2 """
3 Function Closures and Annotation Scopes
4
5 This file demonstrates Python’s closure mechanism and how
annotations
6 are handled in different scopes. It shows how free
variables are
7 captured and how annotations are evaluated.
8 """
9 from typing import Callable, List
10
11 def make_counter(start: int = 0) -> Callable[[], int]:
12 """Creates a counter function with its own private
state."""
13 count = start
14
15 def counter() -> int:
16 nonlocal count

Alejandro Sánchez Yalí


Software Developer | AI & Blockchain Enthusiast
€ www.asanchezyali.com
PYTHON NAMESPACES

17 current = count
18 count += 1
19 return current
20
21 return counter
22
23 def make_multiplier(factor: float) -> Callable[[float],
float]:
24 """Creates a function that multiplies its input by a
stored factor."""
25 # ’factor’ is a free variable captured by the closure
26 def multiplier(x: float) -> float:
27 return x * factor
28
29 return multiplier
30
31 # Demonstrate closure behavior
32 print("Closure demonstration:")
33 counter1 = make_counter(5)
34 counter2 = make_counter(10)
35
36 print(f"Counter 1: {counter1()}, {counter1()},

Alejandro Sánchez Yalí


Software Developer | AI & Blockchain Enthusiast
€ www.asanchezyali.com
PYTHON NAMESPACES

{counter1()}")
37 print(f"Counter 2: {counter2()}, {counter2()},
{counter2()}")
38
39 # Demonstrate multiple closures with the same free variable
40 print("\nMultiplier demonstration:")
41 double = make_multiplier(2)
42 triple = make_multiplier(3)
43
44 print(f"Double 5: {double(5)}")
45 print(f"Triple 5: {triple(5)}")
46
47 # Demonstrate late binding behavior
48 def create_functions() -> List[Callable[[], int]]:
49 """Demonstrates late binding behavior in closures."""
50 functions = []
51 for i in range(3):
52 def func(captured_i=i): # Use default argument
for early binding
53 return captured_i
54 functions.append(func)
55 return functions

Alejandro Sánchez Yalí


Software Developer | AI & Blockchain Enthusiast
€ www.asanchezyali.com
PYTHON NAMESPACES

56
57 print("\nLate binding demonstration:")
58 funcs = create_functions()
59 for f in funcs:
60 print(f"Function returns: {f()}")
61
62 # Demonstrate annotation scopes
63 def outer(x: ’TypeVar’) -> None:
64 y: ’TypeVar’ # Forward reference in annotation
65
66 class TypeVar:
67 pass
68
69 y = TypeVar() # This refers to the local TypeVar class
70 print(f"Type of y: {type(y).__name__}")
71
72 print("\nAnnotation scope demonstration:")
73 outer(None) # The ’TypeVar’ in the annotation is treated
as a string

This example demonstrates several advanced concepts:


• Each function call creates a new instance of the local variables
• Closures can "remember" values from the enclosing scope

Alejandro Sánchez Yalí


Software Developer | AI & Blockchain Enthusiast
€ www.asanchezyali.com
PYTHON NAMESPACES

• The nonlocal keyword is needed to modify enclosed variables


• Type annotations in closures follow special scoping rules

3.2. Key Insights About Closures


When working with closures in Python:

• Each function call creates a new instance of the local variables


• Closures can "remember" values from the enclosing scope
• The nonlocal keyword is needed to modify enclosed variables
• Type annotations in closures follow special scoping rules

3.3. Best Practices with Closures


When using closures in your code:

• Use closures to create functions with private state


• Be careful with mutable free variables
• Consider using default arguments for early binding when needed
• Document the closure’s behavior and any captured variables

Alejandro Sánchez Yalí


Software Developer | AI & Blockchain Enthusiast
€ www.asanchezyali.com
PYTHON NAMESPACES

4. Name Resolution Rules: LEGB


Python follows the LEGB rule when looking up names:

• Local: Names declared inside the current function


• Enclosing: Names in enclosing functions
• Global: Names declared at module level
• Built-in: Names in the built-in module

Python searches these namespaces in this order until it finds the name or raises
a NameError.

5. Best Practices
When working with namespaces in Python:

• Use global sparingly - it can make code harder to understand


• Prefer passing values as arguments and returning results
• Be careful with mutable class variables
• Use clear and descriptive names to avoid confusion
• Document when you need to use global or nonlocal

Alejandro Sánchez Yalí


Software Developer | AI & Blockchain Enthusiast
€ www.asanchezyali.com
PYTHON NAMESPACES

6. References
• Python Documentation. (2025). Python Scopes and Namespaces. Link
• Python Documentation. (2025). The global statement. Link
• Python Documentation. (2025). The nonlocal statement. Link
• Lutz, M. (2023). Learning Python, 6th Edition. O’Reilly Media.
• This article was edited and written in collaboration with AI. If you find any
inconsistencies or have suggestions for improvement, please don’t hesi-
tate to open an issue in our GitHub repository or reach out directly.

7. Explore More Python Concepts

Enjoyed This Content?


Don’t miss my other Python articles:
Python Decorators: A Comprehensive Guide

Learn how to write and use decorators in Python to enhance your


functions and classes with additional functionality.

Alejandro Sánchez Yalí


Software Developer | AI & Blockchain Enthusiast
€ www.asanchezyali.com
Feedback

Found this helpful?


Save, comment and share
May 2, 2025

You might also like