Python nonlocal Keyword (original) (raw)
The **nonlocal keyword in Python is used within nested functions to indicate that a variable refers to a previously bound variable in the nearest enclosing but non-global scope. This allows modification of variables in an outer function from within an inner function without making them global.
**Example:
Python `
def outer(): message = "Hello"
def inner():
nonlocal message # Reference the enclosing variable
message = "Hello, Python!" # Modify it
print("Inside inner:", message)
inner()
print("Inside outer:", message)outer()
`
Output
Inside inner: Hello, Python! Inside outer: Hello, Python!
Explanation: Here, nonlocal message ensures that message inside inner() modifies the message variable from**outer() instead of creating a new local variable.
Why use nonlocal ?
In Python, variables have different scopes:
- **Local Scope: Variables defined inside a function.
- **Enclosing Scope: Variables in an enclosing function but not global.
- **Global Scope: Variables declared at the top level of the script.
- **Built-in Scope: Names preassigned in Python.
When a variable is declared inside a function, it is local by default. The nonlocal keyword allows modifying an enclosing function's variable instead of creating a new local variable.
nonlocal vs global
While both nonlocal and global allow modifying variables from an outer scope, their scope is different:
| Keyword | Scope affected | can modify local variable ? | can modify global variable ? |
|---|---|---|---|
| nonlocal | Enclosing (non-global ) function scope | Yes | No |
| global | global scope | No | Yes |
**Example:
Python `
a = "I am global"
def outer(): b = "I am enclosing"
def inner():
global a
nonlocal b
a = "Modified global"
b = "Modified enclosing"
inner()
print("Inside outer:", b)outer() print("Outside outer:", a)
`
Output
Inside outer: Modified enclosing Outside outer: Modified global
Explanation: Here,**a is modified globally using global, while**b** is modified in the enclosing scope using nonlocal.
Rules and Restrictions of non local
- It cannot reference global or local variables; it only works within nested functions.
- The variable being referenced must exist in the nearest enclosing function scope.
nonlocalcannot be used at the module level or in a function without an enclosing scope.
**Example: Incorrect usage
Python `
Global variable
global_a = 'geeksforgeeks'
def outer(): def inner(): nonlocal global_a # Attempting to reference global variable global_a = 'GeeksForGeeks' # Modifying the variable print(global_a) inner() outer()
`
**Output:
Hangup (SIGHUP)
File "/home/guest/sandbox/Solution.py", line 6
nonlocal global_a # Attempting to reference global variable
^^^^^^^^^^^^^^^^^
SyntaxError: no binding for nonlocal 'global_a' found
**Explanation: This will result in an error because nonlocal can only reference variables from an enclosing function, not from the global scope.
Scope resolution with nonlocal
When multiple nested functions have a variable with the same name, nonlocal references the nearest enclosing function’s variable, not the global one.
Python `
def fun1(): name = "geek"
def fun2():
name = "Geek"
def fun3():
nonlocal name
name = 'GEEK' # Modify before using
print(name)
fun3()
print(name) # Modified value in fun2()
fun2()
print(name) # Unchanged value in fun1()fun1()
`
**Explanation: fun3() uses nonlocal to modify name in **fun2() to "GEEK", which both **fun3() and fun2() print. **fun1() remains unaffected, printing "geek", showing nonlocal affects only the nearest enclosing scope.
Practical application of nonlocal
One common use case of nonlocal is maintaining state in closures, such as implementing a counter function.
Python `
def counter(): count = 0 # Enclosed variable
def increment():
nonlocal count # Reference count from the outer function
count += 1
return count
return incrementCreate a counter instance
counter1 = counter()
print(counter1())
print(counter1())
print(counter1())
`
**Explanation: This code uses **nonlocal in a closure to maintain count across calls, allowing **increment() to update and return it.
Advantages of nonlocal
- Allows access to variables in an upper scope (excluding global scope).
- Saves memory by reusing the referenced variable’s memory address.
- Useful in closures where state persistence is needed.
Disadvantages of nonlocal
- Cannot be used for global or local scope variables.
- Only applicable within nested functions.