The Reason Behind if __name__ == ‘__main__’ in Python
Why is it necessary?
You might have seen this one before: the syntax which often gets ignored because it doesn’t seem to hinder the execution of your code. It may not seem necessary, but that’s only if you’re working with a single Python file.
Let’s Get Right Into It!
Let’s start out by deconstructing the statement from left to right. We already know what an if statement is; however, the most important part of the statement are the two things being compared.
Let’s start with __name__
.This is used to denote the name of the file that is currently being run, but there is a trick to this. The file currently being run will always have the value __main__
.
This sounds confusing at first but let’s clarify.
Let’s create two Python files:
current_script.py
other_script.py
Please ensure these files are in the same directory/folder.
Inside the other_script.py
file, we’ll add a two-print statement, just as shown below.
print("****inside other script.py*****")print("__name__ is ",__name__)
Run this other_script.py
file.
Note: I will be running this file while using Python within the terminal, just as illustrated below. Also note that I am working from a Windows operating system.
python other_script.py
Output:
****inside other script.py*****
__name__ is __main__
Now you realize that it’s just as I stated before. The file being executed will always have the value __main__
. This represents the point of entry into our application.
In Python and pretty much every programming language, we can import other files into our application. We’ll now go into our current_script.py
and input the following code:
import other_scriptprint("")print("****inside current script.py*****")print("__name__ is ",__name__)
The code above imports the other_script.py
with the import
statement at the top, which is followed by print(“****inside current script.py*****”)
to verify that we are in thecurrent_script.py
file.
Be aware that because we imported other_script
at the top of the file, this therefore means that the entire contents of other_script.py
will now be injected into where import other_script
is.
Before we continue, take keen note of the input of when we ran other_script.py
. Now observe what happens when we execute current_script.py
.
python current_script.py
Output:
****inside other script.py*****
__name__ is other_script****inside current script.py*****
__name__ is __main__
You will now realize that previously when we ran other_script.py
, it gave us the value for __name__
as __main__
. But now since we ran it as an import in current_script.py
, the value of __name__
suddenly changed to the name of the imported script which is other_script
.
Furthermore, the value of __name__
for current_script.py
is __main__
. This goes back to what I had highlighted previously: The file currently being run will always have the value __main__
.
Let’s put this all together now.
The file you are currently running will always be __main__
, while any other imported files will not be. Those will have the name of their respective files.
Use Cases
This syntax comes in handy when you have programs that have multiple Python files.
Let’s create a program that has two classes. A Name
class and a Person
class. These two classes will be placed in two separate files, name.py
and person.py
. The Person
class uses theName
class in this system.
We’ll start out by building the Name
class in the name.py
file. This is a simple class that has only two attributes, fname
(first name) and lname
(last name) along with their corresponding getters and setters.
__repr__
is the default output when the object is printed.
We added our syntax if__name__ == “__main__:”
. Based on our understanding, we can tell that the body of this if statement will only be executed if the main file is the one being executed — meaning it is not an import.
But why do we do this?
We do this because it is one of the most important steps when we want certain operations to be done only on the file we are currently running. In this scenario, we wrote a Name
class and we are testing out its functionalities.
Output:
fname=Jordan;lname=Williams
As you can see from the output above, we were able to test the functionality of the Name
class. However, this concept will not hit home until we’ve built the other class.
Let’s create our person.py
file.
Notice from name import Name
, where I imported the Name
class into our file, it was used on line 7 whereself.name = Name(fname, lname)
.
Output:
201107
John Brown
Male
This is the output from testing our Person
class. Notice that there is no output from the Name
class because it is encased under the condition __name__ == “__main__”
and it is currently not the main file.
Let’s now remove __name__ == “__main__”
from name.py
and see the difference:
Notice that __name__ == “__main__”
is not removed. We will now run our person.py
file.
Output:
fname=Jordan;lname=Williams
201107
John Brown
Male
See, here we only wanted to test the functionality of the Person
class. However, we are getting outputs from the Name
class as well.
This could also be a problem if you had made some Python library and wanted to extend that functionality to another class but do not want that other library to run automatically in your current script.
Other Languages
Some of you who dabble in other programming languages might have noticed that this is the same as the main method or functions found in other languages. Programming languages such as Java with public static void main(String[] args)
, C# with a similar public static void Main (string[] args)
and C with int main(void)
all have some sort of main function or method present to execute multiple files/scripts of code.
Let’s look at the equivalent code in another language.
Let’s look at Java for instance.
Summary
Sometimes you want to run some logic only in the file currently being executed. This comes in handy in testing individual units of code without the hindrance of other files being executed. This can come in handy when building libraries that depend on other libraries. You wouldn’t want a rogue execution of another library in the code you are in.