In this article we will explore the __name__ variable, its purpose and how we can use it to tell where a module or script is being executed from. 

You may have come along the __name__ variable when going through some code, scripts or modules. The following example shows how it is commonly used.

def add(a, b):
    print(f"{a} + {b} = {a + b}")

#use the __name__ variable
if __name__ == "__main__":
    add(10, 20)

In the above example, the statement inside the if block gets executed, meaning that the condition evaluated to True and, therefore, the value held by __name__ is  "__main__". In the next part we will understand why in this case __name__ holds the value "__main__" and when this may not be the case.

Each module in Python contains the special variable, __name__. The variable starts and ends with double underscores which means that you are not supposed to directly alter its value.  Instead, the value is assigned automatically by the interpreter.

Python automatically assigns a value to the __name__ variable depending on how the consisting module is being executed. If a module is being run directly as the main program and not through importation( like in the previous example), __name__ is assigned the value "__main__" .  On the other hand , if the module is being executed as an imported module from shell or another module/script, the __name__ variable will hold a string with the actual name of the module. Consider the following two modules.

this module is to be imported.

#spam.py

#define some functions
def add(a, b):
    '''get sum of a and b'''
    print(f"{a} + {b} = {a + b}")

def prod(a, b):
    '''get the product of a and b'''
    print(f"{a} x {b} = {a * b}")
#foo.py

#import the spam module
import spam

#get the __name__ variable of 'spam.py'
print(spam.__name__)

if __name__ == '__main__':
    spam.add(10, 20)

spam
10 + 20 = 30

In the above example, we have defined the first module,  spam.py which we import from the script, foo.py. As clearly shown, from foo.py, the __name__ variable of the spam module has the value "spam" while the top-level one remains to be "__main__".

Why the __name__ variable is important

When a module is imported, the statements in the imported module actually gets executed where it is imported. This means that if the module carries out some computations or yields output in addition to defining variables, functions and classes, the results of the computation or output will appear where the module is imported. The following simple examples demonstrates this:

to be imported

#spam

print('This is spam.')
#foo.py

#import the spam module
import spam

print('This is foo.')

This is spam.
This is foo.

As shown in the above example, the output from spam.py are seen once the module is imported in foo.py

We can use the __name__ variable in an if statement so that some computations are only carried out if the module is executed directly but not when it is imported. This can help to prevent unnecessary computations from being propagated where the module is imported. Consider the following example.

To be imported

#spam.py

#define some functions
def add(a, b):
    '''get sum of a and b'''
    print(f"{a} + {b} = {a + b}")

def prod(a, b):
    '''get the product of a and b'''
    print(f"{a} x {b} = {a * b}")

if __name__ == '__main__':
    #these statements will not be executed where the module is imported.
    add(1, 2)
    add(3, 4)
    prod(5, 5)
    prod(8, 9)
    add(6, 7)
#foo.py

#import the spam module
import spam

spam.add(10, 20)
spam.prod(8, 9)

10 + 20 = 30
8 x 9 = 72

In the above example we are running the foo.py script. Inside foo.py, the __name__ variable of  'spam.py' is 'spam' and not '__main__' , therefore, statements inside spam's if statements do not get executed. If we had instead run the spam.py directly as a script, the statements would have then been executed.

It is common for libraries and modules meant to be imported to use this technique for testing purposes. For example, you can put code for testing the features of your module inside an if statement as shown and simply run the module as the main program. The statements inside the if block won’t run where the module is imported