Why do we use `if __name__ == “__main__”:` in Python?

Ayush Priya
7 min readNov 24, 2019

Demystifying how to write Modular Code in Python.

Anyone who has done a decent bit of development with Python, surely at some point, has come across the following syntax:

if __name__ == "__main__":
# Statements

I first came across this when I was learning about Flask, the backend framework and though I initially just went along with it, soon enough I was curious to know what exactly did this conditional statement accomplish. Also while working with fellow developers, I realized this particular snippet is something that takes some time to wrap one’s head around. So, I decided I’ll write a short blog on what this conditional statement signifies, why you should and how you can use it when you’re writing your next application.

What is Modular Code?

Before we begin, we should know a little bit about how python works with modules. A module is a snippet of code that can be imported in other scripts and utilized as needed i.e. the file containing the code that is to be imported need not be run explicitly.

Let’s take an example where we have an application that takes a user’s full name as input and greets him by his first name only. Assume there are two python scripts - main.py and module.py where main.py will have the main body of the application and module.py will contain a helper function which we need to use in the application.

In module.py we will define a function that extracts the first name of the user and returns it. Here’s what the code looks like:

# module.pydef extract_first_name(full_name):
# Splits the full name with whitespace as the delimiter
name = full_name.split(" ")
# Returns the first element i.e. the first name
return name[0]

In main.py we’ll have the sequential execution of the steps needed to achieve the broad use of our application, that is, to take someone’s full name and greet him with just his first name. Here’s what the code looks like:

# main.py# Importing a function from the module we wrote
from module import extract_first_name
full_name = input("Enter your full name: ")first_name = extract_first_name(full_name)greeting = "Hello " + first_name + "!"
print(greeting)

Running main.py will give us the following output:

C:\Users> python main.py
Enter your full name: Ayush Priya
Hello Ayush!

As it is evident, the program ran without any errors. So, we just wrote our first custom module and imported it elsewhere as needed. One of the first questions that may have come to your mind after this example is why not have the function inside main.py itself. It’s a valid question too, given there’s not a lot of code in our application right now. But segregating functionality of our application into modules when it has a lot of code makes it cleaner, easier to read and to maintain. It provides a better way to manage the application. Using modular code also helps when we want to reuse code via a module we wrote for one application in another application. For example, you might have written a module that creates a connection to the database and returns an object with which we interact with the database. Now, when we write a new application that requires this functionality, we can reuse the module instead of copy-pasting, or worse, rewriting the same code again.

Hence, it is a good idea to use custom modules to keep your code clean and manageable when working with large applications. It also gives the added benefit of code reusability.

Note: For the application we built above, both the scripts should be in the same directory.

The Significance of __name__ and “__main__”

While running the code we write, Python does a lot of things in the background. It assigns special attributes to certain segments of the applications. The string "__main__" is one of those special attributes. It is a special name that python assigns to the script that was explicitly run by the developer. From the greeting application we wrote earlier, the application we ran explicitly was main.py and hence, in the background, python assigned the name "__main__" to it when we executed it. Just like python assigns special names, it uses special variables to store those special names. The __name__is one such variable that stores the name assigned to the script by python. To test, let’s use the following snippet of code:

# test.pyprint(__name__)

The output after running the above code is:

C:\Users> python test.py
__main__

Now, that we know the significance of __name__ and "__main__", the only thing remains is the conditional statement we began with:

if __name__ == "__main__":
# Statements

The above conditional statement checks if this script was executed explicitly by the developer or not. It allows us to alter how the script behaves when it is run directly and when it is used as a module.

Why and how to use `if __name__ == “__main__”:`

Let’s see how this syntax is extremely helpful when one has custom modules in their application. Going back to our greeting application, assume we want to change how the function in module.py worked. Instead of returning the first name, we now want it to return a string that has the initial character of the last name followed by the first name. So, “John Hancock” would be returned as “H. John”. Modifying the code for the function leaves us with the following:

# module.pydef extract_first_name(full_name):
# Splits the full name with whitespace as the delimiter
name = full_name.split(" ")
# Returns last name's initial character followed by first name
return name[1][0] + ". " + name[0]

Now, to test if our modified code works we can execute main.py and provide a sample input name. In the scenario of our greeting application, it is fine to do so as there’s not a lot going on in main.py itself, but when writing large applications, it’s a better practice to individually test modules rather than running the entire application to see if the changes made to the module work or not. To achieve this we need to execute our module.py and call our function with a test name passed as a parameter to the function like so:

# module.pydef extract_first_name(full_name):
# Splits the full name with whitespace as the delimiter
name = full_name.split(" ")
# Returns the first element i.e. the first name
return name[1][0] + ". " + name[0]
print("---Running Module Test---")
name = extract_first_name("John Hancock")
print(name)

Running the test on our modified module.py gives us the following output:

C:\Users> python module.py
---Running Module Test---
H. John

Great! So, the modification works. Let’s now run main.py as well to make sure everything works as we want it to:

C:\Users> python main.py
---Running Module Test---
H. John
Enter your full name: John Hancock
Hello H. John!

I’m sure that you too see that this is not what we want our greeting application to do. One question that you might have is why do we see the test output from module.py when we didn’t execute it, we just imported it in main.py and used the function. It happened because there is one thing that we didn’t talk about in the previous section about modular code.

When we import a module in python, the module gets executed even without us executing it.

So, when we imported module.py in our application, it executed the script thus, printing the test content we wrote. Now, we need to eliminate the test output’s content. One (dirty) way to do this is to just delete the code that we used to test the modifications but that will require us to write it back every time we want to test it again against new modifications. A better way is to use a mechanism to check who is executing the module, us or python. We want to see the test output if we are executing the module but not when python executes it while importing it in other scripts. This is where it all comes together! We can achieve this desired functionality as we know that when we execute module.py explicitly, python will assign it a special name, "__main__" and we can use this to alter how module.py behaves. Let’s add the if-statement to module.py:

# module.pydef extract_first_name(full_name):
# Splits the full name with whitespace as the delimiter
name = full_name.split(" ")
# Returns the first element i.e. the first name
return name[1][0] + ". " + name[0]
# This segment is executed only if the script is ran explicitly
if __name__ == "__main__":
print("---Running Module Test---")
name = extract_first_name("John Hancock")
print(name)

Now, when we execute module.py and main.py we get the following outputs, respectively:

C:\Users> python module.py
---Running Module Test---
H. John
C:\Users> python main.py
Enter your full name: John Hancock
Hello H. John!

And with that, we have our application complete. When we want to test a new modification to our module, we’d just execute it directly with some test cases and it won’t hamper how the application works as a whole. We won’t even have to add and delete test cases and code and hence, any modifications can be tested with minimal effort as the test cases can be reused and be kept within the module at all times.

Conclusion

We took a look at what exactly is meant by modular code and how to write it in python. We saw a few special attributes that python assigns to scripts based on conditions like “how was this script executed?” and we also looked at how do we use the conditional if __name__ == "__main__": to alter the behavior of modules when we are testing them and when they are being imported.

--

--