Scope, State, and Closures in Python
Understanding scope is crucial for writing bug-free Python code. Scope defines the “visibility” of a variable—where in your program you can access it. Closely related is a variable’s lifetime, which is how long it exists in memory.
These concepts come together in a powerful feature called closures, where a function “remembers” the environment in which it was created.
The LEGB Rule for Name Resolution
When you use a variable name, Python has a strict order of places it looks for that name. This is known as the LEGB Rule.
1. L
ocal
The first place Python looks is inside the current function’s local scope. These are variables defined directly within the function.
2. E
nclosing
If the name isn’t found locally, Python looks in the scopes of any enclosing functions, from the innermost to the outermost. This is relevant for nested functions.
3. G
lobal
If the name still isn’t found, Python checks the module-level (global) scope. These are variables defined at the top level of your script.
4. B
uilt-in
Finally, if the name is nowhere to be found, Python checks the built-in scope, which contains all the names that are always available, like print()
, len()
, and str()
.
If Python fails to find the name in any of these scopes, it raises a NameError
.
Pyground
Given a nested function structure with a variable `x` defined at multiple levels, predict the output.
Expected Output:
Inside inner_function, x is: I am Local Inside outer_function, x is: I am Enclosing In the main script, x is: I am Global
Output:
Modifying Variables in Different Scopes
By default, you can only read from outer scopes. If you assign a value to a variable inside a function, Python assumes it’s a new local variable. To modify variables in outer scopes, you need special keywords.
Local Scope
Variables created inside a function are local to it. Their lifetime is tied to the function call; they are created when the function starts and destroyed when it returns.
Pyground
What happens if you try to access a local variable from outside its function?
Expected Output:
I exist only inside this function.