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__':
...
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")
myscript.py
import mylib
print("In myscript")
If we run
python mylib.py
it will print
In mylib
This is not surprising we told it to do just that.
If we run
python myscript.py
it will print
In mylib
In myscript
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():
...
myscript1.py
import mylib
print("In myscript")
myscript2.py
import mylib
print("In myscript")
mylib.display()
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
we only see
In myscript
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
we see
In myscript
In mylib
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
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()
myscript1.py
import mylib
print("In myscript")
myscript2.py
import mylib
print("In myscript")
mylib.display()
Now if we run
$ python mylib.py
We get
In mylib
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__}'")
myscipt.py
import mylib
print(f"In myscript __name__='{__name__}'")
Running mylib:
python mylib.py
We get:
In mylib __name__='__main__'
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
We get the following:
In mylib __name__='mylib'
In myscript __name__='__main__'
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__':
...
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.
Top comments (7)
As a software engineer who doesn't use Python as a primary language, I understood "that" this was needed, but not the underlying "why". Not only was your information succinct and well written, but you have just enough background to answer my side questions as they cropped up with a little history on the subject.
I'll be subscribing to your content. Keep up the excellent work!
What do you mean by "it seems like a back engineering practice that will backfire"?
Probably I meant bad I'll check when I get back to my computer
Ah, ok :D
Still, I'd like to know why you think it's bad engineering.
so yeah, I can confirm I meant "bad engineering practice" I fixed it. Thanks for mentioning. As for why?
I am not sure I have some good explanation now, but it feels like a better division of responsibilities. It seems like this practice is something that was needed when people had scripts and then asked themselves "how could I use part of this script in some other script" and instead of moving the shared function to a separate file - a module - they kept the old structure. Maybe they or their bosses feared the change. (Common at corporations.)
Thereby making one of the scripts responsible for both being a script on its own and serving other scripts.
However, I'd be interested to hear your opinion and if you have other use cases where you think it is required or useful.
I have never really thought about it. When I learnt python, my boss just said "this is the equivalent of
int main()
in C" and that was that. I suppose it's not necessary if you don't call functions at the module level.The python documentation notes that it is a "common idiom", so I guess it's good notation to give other devs pointer where to look.
Since I posted this I thought a bit more and I have a few more use-cases where people use this idiom. In some of those cases it can be useful. I'll update the article with them.