Contents

Understanding the if __name__ == '__main__' in Python scripts

The __main__ name

Every object in Python has attributes and we access them using the dot notation <object>.<attribute name>. A Python module is an object itself and has attributes too. One of them is the __name__ attribute which holds the name of the file. When we import a Python module we use that as the object to access its name by typing <module>.__name__ or if accessing the __name__ attribute within a file. Executing python foo.py:

1
2
3
# foo.py
import bar
print(bar.__name__)  # prints bar
1
2
# bar.py
print(__name__)  # prints bar

In the example above I intentionally did not print foo's __name__ to avoid confusion. The reason is that when Python executes a script sets that script’s name to __main__.

1
2
3
4
# foo.py
import bar
print(bar.__name__)  # prints bar
print(__name__)  # prints __main__

From Python docs:

'__main__' is the name of the scope in which top-level code executes…
A module can discover whether or not it is running in the main scope by checking its own __name__

When importing a script, Python executes the code of that file. So if you have something like this:

1
2
3
4
5
6
# spam.py
def foo(): print('foo')

def bar(): print('bar')

foo()

and you import spam, Python will execute the foo() function in the last line. But how can you import foo function avoiding any execution and on the same time being able to run $ python spam.py which will call foo() in the last line? By checking the name of the file when importing or executing it.

Again, every Python file has its __name__ attribute set to its file name, except for the file that was ran by Python, which gets the __main__ as name.

1
2
3
4
5
6
7
# spam.py
def foo(): print('foo')

def bar(): print('bar')

if __name__ == '__main__':
    foo()

When the file is being executed by Python it will get the name __main__, thus will run foo(). When it gets imported (which means another file was executed by Python) will get as name the name of its file: spam.

I hope it cleared up the confusion about scripts having in the end the if __name__ == '__main__' :)