Understanding if __name__==’__main__’ in Python

Posted on
Understanding if __name__==’__main__’ in Python

In this guide, you will understand the functionality and significance of if __name__ == ‘__main__’ in Python.

Have you ever skimmed through a Python codebase with different modules?

If yes, you’d probably have come across if __name__ == ’__main__’ conditional in one or more modules. Over the next few minutes, we’ll demystify what the above conditional means and look at an example where it can be helpful.

Let’s begin!

What is the Significance of __name__ in Python?

What is the Significance of __name__ in Python?

In Python, a module is a .py file that contains function definitions, a set of expressions to be evaluated, and more. For example, if  we have a file named hello_world.py, we refer to this as the hello_world.py file or the hello_world module.

When you run a Python module, the Python interpreter sets the values for a few special variables ahead of execution: __name__ is one of them. The key to understanding the significance   __name__ is understanding how imports work in Python.

? Download the code for this section here.

Head over to the folder example-1. We have the file module1.py. The __name__ variable is in the namespace of the current module.

This module prints out a line followed by the value of the __name__ variable.

# example-1/module1.py
print("This is module1.")
print(f"The __name__ variable of module 1 is: {__name__}.")

Now, let’s run module1 from the command line.

$ python module1.py

In the output, we see that the __name__ variable is set to __main__.

This is module1.
The __name__ variable of module 1 is: __main__.

Importing Modules in Python

In addition to running a Python module, you may sometimes want to use functionality from another Python module inside the current module. Python facilitates this through imports.

Imports let you reuse the functionality of another module—by importing it into the current module’s scope—without having to rewrite the code.

Importing Modules in Python

The module2.py file contains the following. We have imported module1 inside. module2.

# example-1/module2.py

import module1 # module1 is imported

print(f"This is module2")
print(f"The __name__ variable of module2 is: {__name__}.")

We run module2.py and observe the output.

$ python module2.py

In the output below:

  • We see that module1 is run under the hood when we import it inside module2, and the corresponding output is printed out.
  • But this time, the __name__ variable is not __main__ but module1.
  • Because we ran module2 directly, the __name__ variable corresponding to the module is now __main__.
Output

This is module1.
The __name__ variable of module 1 is: module1.
This is module2
The __name__ variable of module2 is: __main__.

? Key Idea:

– If a module  is run directly, its __name__ variable is set to is equal to __main__

– If a module is imported inside another module, its __name__ is set to the name of the module.

Example of if __name__==’__main__’ in Python

Example of if __name__=='__main__' in Python

In the section, we’ll see a practical use case of the if __name__ == ‘__main__’ conditional. We’ll define a simple function and then write unit tests to check if the function is working as expected.

? Download the code and follow along.

The code for this section can be found in the example-2 folder.

Here, add.py is a Python file that contains the definition of the function add_ab().The function add_ab() takes in any two numbers and returns their sum.

# example-2/add.py

def add_ab(a,b):
    return a + b
unit test

We’ll use Python’s unittest module to test the function add_ab().

Writing Test Cases for a Python Function

Look at the code snippet below, containing the contents of the test_add module.

# example-2/test_add.py

import unittest
from add import add_ab

class TestAdd(unittest.TestCase):
    def test_add_23(self):
        self.assertEqual(add_ab(2,3), 5)
    
    def test_add_19(self):
        self.assertEqual(add_ab(1,9), 10)
    
    def test_add_1_minus7(self):
        self.assertEqual(add_ab(1,-7), -6)
    

The above code does the following:

  • Imports Python’s built-in unittest module
  • Imports the function add_ab() from the add module
  • Defines the test class TestAdd and a set of test cases as methods within the test class

To set up unit tests for your code, you should first define a test class that inherits from unittest.TestCase. All test cases should be specified as methods inside the class and should start with test_.

Note:  If you do not name the methods as test_, you’ll see that the corresponding tests will not be detected, and therefore, will not run.

Now let’s try running the test_add module from the terminal.

$ python test_add.py

You’ll see that there is no output, and none of the tests have run.

Why is this the case??

This is because to run the unit tests, you should run unittest as the main module while running test_add.py, using the command below.

$ python -m unittest test_add.py

Upon running the above verbose command, we see that all three tests have run successfully.

Output
...
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK

However, it will be convenient to run the tests when this module test_add is run, yes? Let’s learn how to do it in the next section.

Using if __name__ == ‘__main__’ to Run unittest as the Main Module

Run unittest as the Main Module

If you’d like to run all the unit tests when the module runs directly, you can add the conditional.

# example-2/test_add.py

import unittest
from add import add_ab

class TestAdd(unittest.TestCase):
    def test_add_23(self):
        self.assertEqual(add_ab(2,3), 5)
    
    def test_add_19(self):
        self.assertEqual(add_ab(1,9), 10)
    
    def test_add_1_minus7(self):
        self.assertEqual(add_ab(1,-7), -6)

# Run unittest as the main module
if __name__ == '__main__':
        unittest.main()

The conditional in the above code snippet tells the Python interpreter: If this module is run directly, then run the code inside. unittest.main().

You can run the test_add module after adding the above two lines of code.

$ python test_add.py

▶️ Running the test add module directly now runs all the three tests we’ve defined.

Output
...
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK

The above output OK indicates that all the tests were run successfully. The three dots … indicate that three tests were run, and all passed.

Now, let us change the expected return value test_add_1_minus7 to 8. Because the function returns – 6 in this case, there should be one failing test.

def test_add_1_minus7(self):
        self.assertEqual(add_ab(1,-7), 8)

As seen in the output below, we get .F., of the three tests, pattern one of them failed (the second test), and in the traceback, we get a AssertionError stating – 6 != 8.

Output
.F.
======================================================================
FAIL: test_add_1_minus7 (__main__.TestAdd)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_add.py", line 12, in test_add_1_minus7
    self.assertEqual(add_ab(1,-7), 8)
AssertionError: -6 != 8

----------------------------------------------------------------------
Ran 3 tests in 0.021s

FAILED (failures=1)

One important thing to note is that the tests do not necessarily run in the same order in which they are specified in the test class. In the above example, test_add_1_minus7 is defined as the third method in the test class, but the corresponding test was run second.

Summing Up

I hope this tutorial helped you understand how the if __name__ == ‘__main__’ conditional works in Python. 

Here’s a quick recap of the key takeaways:

  • The Python interpreter sets the __name__ variable before executing the Python script.
  • When you run a module directly, the value of the __name__ is __main__.
  • When you import a module inside another Python script, the value of the __name__ is the module name.
  • You can use if __name__ == ‘__main__’ to control execution and which parts of the module run during direct and imported runs, respectively.

Next, check out this in-depth guide on Python sets. Happy learning!?