What does "if __name__ == '__main__'" do in Python?

Gabor Szabo - Dec 7 '22 - - Dev Community

You might have seen the following code snippet in many Python files and wondered what does that do and why would you need it?

if __name__ == '__main__':
    ...
Enter fullscreen mode Exit fullscreen mode

In a nutshell it allows a file to be used both as a stand-alone program (script) and as a module imported by some other stand-alone program.

Let's see the explanation.

Loading a file as a module

A little background:

Let's say we have the following two files:

mylib.py

print("In mylib")
Enter fullscreen mode Exit fullscreen mode

myscript.py

import mylib

print("In myscript")
Enter fullscreen mode Exit fullscreen mode

If we run

python mylib.py
Enter fullscreen mode Exit fullscreen mode

it will print

In mylib
Enter fullscreen mode Exit fullscreen mode

This is not surprising we told it to do just that.

If we run

python myscript.py
Enter fullscreen mode Exit fullscreen mode

it will print

In mylib
In myscript
Enter fullscreen mode Exit fullscreen mode

This is probably not what we wanted. The print of the imported module was executed and it was executed before the print of our script.
Usually we don't expect anything to happen while we import modules. Definitely nothing to be printed to the screen.

It happened, because when Python imports a file (a module) it executes it at the time of import which means any code outside of
functions will be executed.

It is very rare that in module that we import there is any code outside of functions. So the better approach to write a module would be this:

Having only functions in modules

mylib.py

def display():
    print("In mylib")

def destroy_harddisk():
    ...
Enter fullscreen mode Exit fullscreen mode

myscript1.py

import mylib

print("In myscript")
Enter fullscreen mode Exit fullscreen mode

myscript2.py

import mylib

print("In myscript")

mylib.display()
Enter fullscreen mode Exit fullscreen mode

Now we have two functions in our mylib.py file. One of them is the display function we would like to use
and the the other is the destroy_harddisk that you would probably not want to execute. I have not even implemented
it to make sure no one will run it and then come complaining.

If we run the first script

python myscript1.py
Enter fullscreen mode Exit fullscreen mode

we only see

In myscript
Enter fullscreen mode Exit fullscreen mode

This is not surprising as now, even though we imported the mylib module, we did not call any of its functions.

n order to see the text from the display function we need to call it:

If we run the second script

python myscript2.py
Enter fullscreen mode Exit fullscreen mode

we see

In myscript
In mylib
Enter fullscreen mode Exit fullscreen mode

This time the content of mylib.py display function is printed at the time when it is called.

However if we now run

python mylib.py
Enter fullscreen mode Exit fullscreen mode

There is no out. So in order to facilitate the needs of the scripts that import the mylib.py we changed the behavior of the mylib.py
and "ruined" it.

What we would really like is to see the output of the display function when execute python mylib.py.

Make both cases work

This is where the expression comes in handy.

mylib.py

def display():
    print("In mylib")

def destroy_harddisk():
    ...

if __name__ == '__main__':
    display()
Enter fullscreen mode Exit fullscreen mode

myscript1.py

import mylib

print("In myscript")
Enter fullscreen mode Exit fullscreen mode

myscript2.py

import mylib

print("In myscript")

mylib.display()
Enter fullscreen mode Exit fullscreen mode

Now if we run

$ python mylib.py
Enter fullscreen mode Exit fullscreen mode

We get

In mylib
Enter fullscreen mode Exit fullscreen mode

just as we got in the first case, and if we run python myscript1.py or python myscript2.py that will act as that did in the second case.

So now we have a file (mylib.py) that can be used both as a module and as a stand-alone program (script).

How does __name__ == "__main__" work?

Let's take the first example and make it print the content of the variable __name__.

mylib.py

print(f"In mylib __name__='{__name__}'")
Enter fullscreen mode Exit fullscreen mode

myscipt.py

import mylib

print(f"In myscript __name__='{__name__}'")
Enter fullscreen mode Exit fullscreen mode

Running mylib:

python mylib.py
Enter fullscreen mode Exit fullscreen mode

We get:

In mylib __name__='__main__'
Enter fullscreen mode Exit fullscreen mode

So when you run the file as a stand-alone program the variable __name__ contains the strange string __main__.

What if we run the program / script?

python myscript.py
Enter fullscreen mode Exit fullscreen mode

We get the following:

In mylib __name__='mylib'
In myscript __name__='__main__'
Enter fullscreen mode Exit fullscreen mode

Now we have two different variables called __name__. One of them in the file mylib.py. There it contains mylib
and one in myscript.py that contains __main.

Our focus should be the fact that the content of the variable in mylib.py depends on how it was used. When we used it
as a stand-alone script it had __main__ in it and when we imported it as a module then it had mylib (the name of the file without the extension)
in it.

Now if you go back to the 3rd example to the code we are trying to understand that you can also see here:

if __name__ == '__main__':
    ...
Enter fullscreen mode Exit fullscreen mode

The condition checks the content of the __name__ variable and calls the display() function
only if it contain __main__ meaning that the file was used as a stand-alone program.

When to use it?

Now that we know what does it do and how does it work, let's ask the question when to use it?

The answer is that it is actually rarely needed.

It can be used to allow a module to be self-testing so we would run the tests of the file when it is executed as a stand-alone program.
However these days it is much more common to put our tests in separate files and even if we include documents that need to be verified using
doctest, pytest can execute those without this construct.

It can be used to make a module also a stand-alone script, but it seems like a bad engineering practice that will backfire.

However it must be used when you use multiprocessing on Windows because that module works by loading your main script as a module.

There might be some other cases as well when it is useful or even required, but I think in general it is needed a lot less than it is actually used.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .