4: Scope, Lifetime, and Closure¶
Summary¶
A variable that a function assigns to is created as a local variable
To reference a global variable that a a function assigns to, it has to be declared as global
Functions can be defined within other functions and the inner functions have access to the containing functions local variables, but not vice versa
if an inner functions assigns to a variable then it is created as a local variable
To refer to a local variable of a containing function in an assignment you have to declare the variable nonlocal
- Closure is a natural consequence of function objects outliving their local variables
If an inner function exists and can be invoked after its containing function has ended, then it still has access to the same local variables via the closure
The closure consists of all of the variables in scope when a function is declared
All functions declared within the same execution context share that context as their closure
The values of variables in the closure are the last values they had before the outer function terminated
Closures has many uses, but the main ones are to provide private state variables, provide a self-reference, and to provide context to callback functions
You can work with the “__closure__” magic attribute to access, and even change, the closure, but how this works is platform-dependent.
Program¶
# Global variable
counter = 100
def outer_function(message):
# Local variable to outer_function
outer_var = "Outer Variable"
print("Inside outer_function:")
print("Local outer_var:", outer_var)
print("Accessing global counter:", counter)
print()
def inner_function():
# Local variable to inner_function
inner_var = "Inner Variable"
# Using nonlocal to modify outer_function's variable
nonlocal outer_var
outer_var = "Outer Variable Modified by Inner"
print("Inside inner_function:")
print("Local inner_var:", inner_var)
print("Modified outer_var:", outer_var)
print("Accessing global counter:", counter)
print("Message from outer_function:", message)
print()
return inner_function # Returning inner function (closure)
# Create closure
closure_example = outer_function("Hello from closure!")
# Call the returned inner function
closure_example()
print("Back in global scope:")
print("Global counter:", counter)
Program Output¶
(docs-env) root@BMitchellLTOP:~/git/sphinx_students/source/programming_lang/book/programs# python3 chapterFour.py
Inside outer_function:
Local outer_var: Outer Variable
Accessing global counter: 100
Inside inner_function:
Local inner_var: Inner Variable
Modified outer_var: Outer Variable Modified by Inner
Accessing global counter: 100
Message from outer_function: Hello from closure!
Back in global scope:
Global counter: 100