Python Namespaces
Python Namespaces
Understanding Python
Namespaces
A Deep Dive into Python’s Name Resolution
May 2, 2025
Source Code
PYTHON NAMESPACES
2. Types of Namespaces
Python has several types of namespaces with different lifetimes:
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}")
38
39 example_function()
40
41 print("\nAfter function call:")
42 print(f"Global x is now: {x}") # Will show the modified
value
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
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}")
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()},
{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
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
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:
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.