In this article, we will understand the concept of variable shadowing in a Python programming language. To understand this concept, we need to be well versed with the scope of a lifetime of variables in python.
Local variables:
When we define a function, we can create variables that are scoped only to that function and are not accessible outside of the function. These variables are referred to as local variables ( as they are local to the function )
Python3
def fn(): # local variable a a = 3 print (a) # Error, variable a referenced before # assignment print (a) |
Output:
NameError: name 'a' is not defined
Global variables
Variables are defined outside of any function and are potentially accessible anywhere in the program.
Python3
# global variable a = 3 def fn(): # print 3 print (a) # print 3 print (a) |
Output:
3
Note: For more information, refer to our Global and Local Variables in Python
Variable shadowing occurs when a variable defined in the inner scope has the same name as a variable in the outer scope. Consider the example below, here the variable inside the function has the same name as a global variable. In this program, there are two versions of variable a, one which is defined globally and the other which is defined within the context of the function. Python treats these variables as completely separate variables. The global variable a is said to be shadowed by the local variable a. The way outer and inner variables with the same name are handled depends upon the name resolution rules of the language.
Python3
# global variable a = 3 def fn(): # local variable a = 5 print (a) # prints 5 fn() print (a) # prints 3 |
5 3
How to avoid variable shadowing?
To modify a global variable, and avoid variable shadowing python provides global keyword which tells python to use the global version of the variable, instead of creating a new locally scoped variable.
Python3
# global variable a = 3 def fn(): global a # global variable modified a = 5 print (a) # prints 3 print (a) # prints 5 fn() |
Output:
3
5
To avoid variable shadowing at the function level, meaning if a variable in outer function has the same name as a variable in an inner function, python provides nonlocal keyword which tells python to use the variable defined in the outer function, instead of creating a new locally scoped variable
Python3
def outer(): a = 5 def inner(): nonlocal a a = 3 print (a) # prints 3 inner() print (a) # prints 3 outer() |
Output:
3
3