Using the nonlocal keyword in Python
The nonlocal keyword is used when you are dealing with variables with same name but in different scopes. Consider a situation where you have a variable 'scope' in a function 'outerFunction'. This function contains another function inside it 'innerFunction', which also has a variable by the name of scope. Any assignment inside the innerFunction will alter the variable of the innerFunction and not of the outerFunction, unless you are using the nonlocal keyword. The nonlocal keyword, used inside the innerFunction tells Python that any assignment to the 'scope' variable should alter the variable in the scope immediately outside of the local scope.
Here is a code example to illustrate the behavior of nonlocal keyword with 2 scopes. The 2 scopes have a variable by the same name. The keyword is used in the inner scope. Outcome is that variable with the same name in the nearest scope (scope 1 in this case) is accessed and assigned a new value.
# Behavior without the nonlocal keyword >>> def outerFunction(): scope = "Scope 1" print("Locals in outerFunction:", locals()) def innerFunction(): scope = "Scope 2" print("Locals in innerFunction:", locals()) print(scope) innerFunction() print(scope) >>> outerFunction() Locals in outerFunction: {'scope': 'Scope 1'} Locals in innerFunction: {'scope': 'Scope 2'} Scope 2 Scope 1 # Behavior with the nonlocal keyword >>> def outerFunction(): scope = "Scope 1" print("Locals in outerFunction:", locals()) def innerFunction(): nonlocal scope scope = "Scope 2" print("Locals in innerFunction:", locals()) print(scope) innerFunction() print(scope) >>> outerFunction() Locals in outerFunction: {'scope': 'Scope 1'} Locals in innerFunction: {'scope': 'Scope 2'} Scope 2 Scope 2 # Code example to illustrate the behavior of nonlocal keyword with 3 scopes. All 3 scopes have a variable by the same name. The keyword is used in the innermost scope. Outcome is that variable with the same name in the nearest scope (scope 2 in this case) is accessed and assigned a new value. # Behavior without the nonlocal keyword >>> def outerFunction(): scope = "Scope 1" print("Locals in outerFunction:", locals()) def interimFunction(): scope = "Scope 2" print("Locals in interimFunction:", locals()) def innerFunction(): scope = "Scope 3" print("Locals in innerFunction:", locals()) print(scope) innerFunction() print(scope) interimFunction() print(scope) >>> outerFunction() Locals in outerFunction: {'scope': 'Scope 1'} Locals in interimFunction: {'scope': 'Scope 2'} Locals in innerFunction: {'scope': 'Scope 3'} Scope 3 Scope 2 Scope 1 # Behavior without the nonlocal keyword >>> def outerFunction(): scope = "Scope 1" print("Locals in outerFunction:", locals()) def interimFunction(): scope = "Scope 2" print("Locals in interimFunction:", locals()) def innerFunction(): nonlocal scope scope = "Scope 3" print("Locals in innerFunction:", locals()) print(scope) innerFunction() print(scope) interimFunction() print(scope) >>> outerFunction() Locals in outerFunction: {'scope': 'Scope 1'} Locals in interimFunction: {'scope': 'Scope 2'} Locals in innerFunction: {'scope': 'Scope 3'} Scope 3 Scope 3 Scope 1 # CONCLUSION: The variable with the same name in the nearest scope (scope 2 in this case) is accessed and assigned a new value.