nonlocal — Advanced Examples
Declares a variable inside a nested function as belonging to the enclosing scope
nonlocal in decorators
Using nonlocal for stateful decorators.
python
import functools def retry(max_attempts=3): def decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): attempts = 0 last_error = None while attempts < max_attempts: try: return func(*args, **kwargs) except Exception as e: attempts += 1 last_error = e print(f" Attempt {attempts} failed: {e}") raise last_error return wrapper return decorator call_count = 0 @retry(max_attempts=3) def flaky_function(): global call_count call_count += 1 if call_count < 3: raise ConnectionError("Network down") return "Success!" print(flaky_function())
Expected Output
Attempt 1 failed: Network down Attempt 2 failed: Network down Success!
Decorators naturally create closures. nonlocal is useful when a decorator needs to maintain state between calls (like counting retries or caching results).
Want to try these examples interactively?
Open Advanced Playground