Python handles variables in a very maverick manner. While many programming languages consider variables as global by default (unless declared as local), Python considers variables as local unless declared the other way round. The driving reason behind Python considering variables as local by default is that using global variables is generally regarded as poor coding practice.
So, while programming in Python, when variable definition occurs within a function, they are local by default. Any modifications or manipulations that you make to this variable within the body of the function will stay only within the scope of this function. Or, in other words, those changes will not be reflected in any other variable outside the function, even if the variable has the same name as the function’s variable. All variables exist in the scope of the function they are defined in and hold that value. To get hands-on experience on python variables and projects, try our data science certifications from best universities from US.
Through this article, let’s explore the notion of local and global variables in Python, along with how you go about defining global variables. We’ll also look at something known as “nonlocal variables”.
Read on!
Global and Local Variables in Python
Let’s look at an example to understand how global values can be used within the body of a function in Python:
Program:
def func():
print(string)
string = “I love Python!”
func()
Output
I love Python!
As you can see, the variable string is given the value “I love Python!” before func() is called. The function body consists just of the print statement. As there is no assignment to the string variable within the body of the function, it will take the global variable’s value instead.
As a result, the output will be whatever the global value of the variable string is, which in this case, is “I love Python!”.
Now, let us change the value of string inside the func() and see how it affects the global variables:
Program:
def func():
string = “I love Java!”
print(string)
string = “I love Python!”
func()
print(string)
Output:
I love Java!
I love Python!
In the above program, we have defined a function func(), and within it, we have a variable string with the value “I love Java!”. So, this variable is local to the function func(). Then, we have the global variable as earlier, and then we call the function and the print statement. First, the function is triggered, calling the print statement of that function and delivering the output “I love Java!” – which is the local variable for that function. Then, once the program is out of the function’s scope, the value of s gets changed to “I love Python”, and that is why we get both the lines as output.
Now, let us add the first two examples, and try to access the string using the print statement, and then try to assign a new value to it. Essentially, we are trying to create a string as both a local and global variable.
Fortunately, Python does not allow this confusion and throws an error. Here’s how:
Program:
def func():
print(string)
string = “I love Java!”
print(string)
string = “I love Python!”
func()
Output (Error):
—————————————————————————
UnboundLocalError Traceback (most recent call last)
<ipython-input-3-d7a23bc83c27> in <module>
5
6 string = “I love Python!”
—-> 7 func()
<ipython-input-3-d7a23bc83c27> in func()
1 def func():
—-> 2 print(string)
3 string = “I love Java!”
4 print(string)
5
UnboundLocalError: local variable ‘s’ referenced before assignment
Evidently, Python does not allow a variable to be both global and local inside a function. So, it gives us a local variable since we assign a value to the string within the func(). As a result, the first print statement shows the error notification. All the variables created or changed within the scope of any function are local unless they have been declared as “global” explicitly.
Defining Global Variables in Python
The global keyword is needed to inform Python that we are accessing global variables. Here’s how:
Program:
def func():
global string
print(string)
string = “But I want to learn Python as well!”
print(string)
string = “I am looking to learn Java!”
func()
print(string)
Output:
I am looking to learn Java!
But I want to learn Python as well!
But I want to learn Python as well!
As you can see from the output, Python recognizes the global variables here and evaluates the print statement accordingly, giving appropriate output.
Also, Check out all trending Python tutorial concepts in 2024.
Using Global Variables in Nested Functions
Now, let us examine what will happen if global variables are used in nested functions. Check out this example where the variable ‘language’ is being defined and used in various scopes:
Program:
def func():
language = “English”
def func1():
global language
language = “Spanish”
print(“Before calling func1: ” + language)
print(“Calling func1 now:”)
func1()
print(“After calling func1: ” + language)
func()
print(“Value of language in main: ” + language)
Output:
Before calling func1: English
Calling func1 now:
After calling func1: English
Value of language in main: Spanish
As you can see, the global keyword, when used within the nested func1, has no impact on the variable ‘language’ of the parent function. That is, the value is retained as “English”. This also shows that after calling func(), a variable ‘language’ exists in the module namespace with a value ‘Spanish’.
This finding is consistent with what we figured out in the previous section as well – that a variable, when defined inside the body of a function, is always local unless specified otherwise. However, there should be a mechanism for accessing the variables belonging to different other scopes as well.
That is where nonlocal variables come in!
Nonlocal Variables
Nonlocal variables are fresh kinds of variables introduced by Python3. These have a lot in common with global variables and are extremely important as well. However, one difference between nonlocal and global variables is that nonlocal variables don’t make it possible to change the variables from the module scope.
Check out the following examples to understand this:
Program:
def func():
global language
print(language)
language = “German”
func()
Output:
German
As expected, the program returns ‘Frankfurt’ as the output. Now, let us change ‘global’ to ‘nonlocal’ and see what happens:
Program:
def func():
nonlocal language
print(language)
language = “German”
func()
Output:
File “<ipython-input-9-97bb311dfb80>”, line 2
nonlocal language
^
SyntaxError: no binding for nonlocal ‘language’ found
As you can see, the above program throws a syntax error. We can comprehend from here that nonlocal assignments can only be done from the definition of nested functions. Nonlocal variables should be defined within the function’s scope, and if that’s not the case, it can not find its definition in the nested scope either. Now, check out the following program:
Program:
def func():
language = “English”
def func1():
nonlocal language
language = “German”
print(“Before calling func1: ” + language)
print(“Calling func1 now:”)
func1()
print(“After calling func1: ” + language)
language = “Spanish”
func()
print(“‘language’ in main: ” + language)
Output:
Before calling func1: English
Calling func1 now:
After calling func1: German
‘language’ in main: Spanish
The above program works because the variable ‘language’ was defined before calling the func1(). If it isn’t defined, we will get an error like below:
Program:
def func():
#language = “English”
def func1():
nonlocal language
language = “German”
print(“Before calling func1: ” + language)
print(“Calling func1 now:”)
func1()
print(“After calling func1: ” + language)
language = “Spanish”
func()
print(“’language’ in main: ” + language)
Output:
File “<ipython-input-11-5417be93b6a6>”, line 4
nonlocal language
^
SyntaxError: no binding for nonlocal ‘language’ found
However, the program will work just fine if we replace nonlocal with global:
Program:
def func():
#language = “English”
def func1():
global language
language = “German”
print(“Before calling func1`: ” + language)
print(“Calling func1 now:”)
func1()
print(“After calling func1: ” + language)
language = “Spanish”
func()
print(“’language’ in main: ” + language)
Output:
Before calling func1: English
Calling func1 now:
After calling func1: German
‘language’ in main: German
If you notice, the value of the global variable (language) is also getting changed in the above program! That is the power that nonlocal variables bring with them!
In Conclusion
In this article, we discussed local, global, and nonlocal variables in Python, along with different use cases and possible errors that you should look out for. With this knowledge by your side, you can go ahead and start practising with different kinds of variables and noticing the subtle differences.
Python is an extremely popular programming language all around the globe – especially when it comes to solving data-related problems and challenges. At upGrad, we have a learner base in 85+ countries, with 40,000+ paid learners globally, and our programs have impacted more than 500,000 working professionals. Our courses in Data Science and Machine Learning have been designed to help motivated students from any background start their journey and excel in the data science field. Our 360-degree career assistance ensures that once you are enrolled with us, your career only moves upward. Reach out to us today, and experience the power of peer learning and global networking!