Ei vielä käännetty
Tätä sivua ei ole vielä käännetty suomeksi, joten se näytetään englanniksi. Auta kääntämään
globals() and locals() Functions Complexity¶
The globals() and locals() functions return dictionary representations of the current global and local namespaces, providing access to all defined variables in those scopes.
Complexity Reference¶
| Operation | Time | Space | Notes |
|---|---|---|---|
globals() |
O(1) | O(1) | Returns reference to existing global dict |
locals() |
O(1) or O(m) | O(1) or O(m) | Module/class scope is O(1); optimized function scopes materialize locals mapping |
| Accessing dict value | O(1) avg | O(1) | Dict key lookup; O(n) worst case with collisions |
Understanding Namespaces¶
Global Namespace¶
# Access global namespace - O(1)
x = 10
y = 20
global_vars = globals() # O(1) - returns reference to existing dict
print(global_vars['x']) # O(1) - access value
print(global_vars['y']) # O(1)
# globals() includes built-ins and module vars
print('print' in globals()) # Usually True (if imported)
Local Namespace¶
# Access local namespace - O(m)
def my_func():
a = 1
b = 2
local_vars = locals() # O(m) - creates dict
print(local_vars['a']) # O(1)
print(local_vars['b']) # O(1)
return local_vars
result = my_func() # O(m)
Common Patterns¶
Inspecting Variables¶
# List all global variables - O(n)
x = 10
y = 20
z = 30
all_vars = globals() # O(1)
# Filter variables (not functions/modules) - O(n)
my_vars = {k: v for k, v in all_vars.items()
if not k.startswith('_')}
print(my_vars) # {'x': 10, 'y': 20, 'z': 30}
Dynamic Variable Access¶
# Access variable by name - O(1)
var_name = 'x'
x = 42
# Using globals()
value = globals()[var_name] # O(1) - get value
# Using getattr for objects
class Config:
timeout = 30
retries = 3
config = Config()
attr_name = 'timeout'
value = getattr(config, attr_name) # O(1)
Getting Caller's Locals¶
import inspect
def get_caller_locals():
"""Get local variables of calling function"""
# Get calling frame
frame = inspect.currentframe().f_back # O(1)
# Access local variables - O(m)
caller_locals = frame.f_locals # O(m)
return caller_locals
def caller():
x = 10
y = 20
caller_vars = get_caller_locals() # O(m)
print(caller_vars) # {'x': 10, 'y': 20}
caller()
Function Scope¶
Module Level¶
# At module level, locals() == globals() - O(1)
X = 100
print(locals() is globals()) # True at module level
print(locals()['X']) # O(1)
Inside Functions¶
# Inside function, locals() is different - O(m)
global_x = 10
def func():
local_y = 20
# Different namespaces
print('local_y' in locals()) # True - O(1)
print('local_y' in globals()) # False - O(1)
print('global_x' in locals()) # False - O(1)
print('global_x' in globals()) # True - O(1)
func()
Modifying Namespaces¶
Setting Global Variables¶
# Modify global namespace - O(1)
globals()['new_var'] = 100 # O(1)
print(new_var) # 100 - variable created!
# Better approach: use globals() sparingly
# Prefer explicit assignment
new_var2 = 200
Setting Local Variables¶
# Modifying locals() has limited effect
def func():
locals()['x'] = 10 # O(1) - sets in dict
try:
print(x) # NameError! - x not actually in local scope
except NameError:
print("x not in local variables")
func()
# Don't use locals() to set variables in function
# Use explicit assignment instead
def func2():
x = 10 # Proper way
print(x) # Works
Practical Examples¶
Debug Function State¶
def debug_state(func_locals):
"""Print local variables with types"""
print("Local variables:")
for name, value in func_locals.items(): # O(m)
if not name.startswith('_'): # Skip special vars
print(f" {name}: {type(value).__name__} = {value}")
def example_func():
x = 42
s = "hello"
lst = [1, 2, 3]
debug_state(locals()) # O(m)
example_func()
Serialize Local Variables¶
import json
def save_state():
"""Save local variables to JSON"""
local_data = locals() # O(m)
# Filter serializable objects - O(m)
serializable = {}
for k, v in local_data.items():
if isinstance(v, (int, str, float, list, dict)):
serializable[k] = v
return json.dumps(serializable)
def task():
count = 10
name = "task"
items = [1, 2, 3]
state = save_state() # O(m)
return state
print(task())
Configuration Registry¶
# Use globals() as simple registry - O(1) per lookup/update
CONFIG = {}
def register_config(name, value):
"""Register configuration"""
globals()[f'config_{name}'] = value # O(1)
def get_config(name):
"""Get configuration"""
return globals().get(f'config_{name}') # O(1)
# Usage
register_config('timeout', 30) # O(1)
register_config('retries', 3) # O(1)
timeout = get_config('timeout') # O(1)
Performance Considerations¶
Frequency of calls¶
# globals() returns same dict object - O(1) each call
for i in range(1000):
d = globals() # O(1) - returns same dict reference
value = d['x']
# Caching is not necessary for globals(), but good for clarity
g = globals() # O(1)
for i in range(1000):
value = g['x'] # O(1) each
Large Namespaces¶
# globals() remains O(1) regardless of namespace size
# Iterating over the returned dict is O(n)
for i in range(10000):
globals()[f'var_{i}'] = i # O(1) each
# Still O(1): returns the same global dict object
g = globals()
# Iteration scales with number of entries - O(n)
names = [k for k in g if k.startswith("var_")]
# Prefer dict for custom data
my_data = {}
for i in range(10000):
my_data[f'var_{i}'] = i # O(1) each
Version Notes¶
- Python 2.x: Same behavior
- Python 3.x: Same behavior
- All versions:
globals()is O(1);locals()semantics are scope- and implementation-dependent