What does if __name__ == "__main__": do?
Whenever the Python interpreter reads a source file, it does two things:
it sets a few special variables like
__name__
, and thenit executes all of the code found in the file.
Let's see how this works and how it relates to your question about the __name__
checks we always see in Python scripts.
Code Sample
Let's use a slightly different code sample to explore how imports and scripts work. Suppose the following is in a file called foo.py
.
# Suppose this is foo.py.
print("before import")
import math
print("before functionA")
def functionA():
print("Function A")
print("before functionB")
def functionB():
print("Function B {}".format(math.sqrt(100)))
print("before __name__ guard")
if __name__ == '__main__':
functionA()
functionB()
print("after __name__ guard")
Special Variables
When the Python interpreter reads a source file, it first defines a few special variables. In this case, we care about the __name__
variable.
When Your Module Is the Main Program
If you are running your module (the source file) as the main program, e.g.
python foo.py
the interpreter will assign the hard-coded string "__main__"
to the __name__
variable, i.e.
# It's as if the interpreter inserts this at the top
# of your module when run as the main program.
__name__ = "__main__"
When Your Module Is Imported By Another
On the other hand, suppose some other module is the main program and it imports your module. This means there's a statement like this in the main program, or in some other module the main program imports:
# Suppose this is in some other main program.
import foo
The interpreter will search for your foo.py
file (along with searching for a few other variants), and prior to executing that module, it will assign the name "foo"
from the import statement to the __name__
variable, i.e.
# It's as if the interpreter inserts this at the top
# of your module when it's imported from another module.
__name__ = "foo"
Executing the Module's Code
After the special variables are set up, the interpreter executes all the code in the module, one statement at a time. You may want to open another window on the side with the code sample so you can follow along with this explanation.
Always
It prints the string
"before import"
(without quotes).It loads the
math
module and assigns it to a variable calledmath
. This is equivalent to replacingimport math
with the following (note that__import__
is a low-level function in Python that takes a string and triggers the actual import):
# Find and load a module given its string name, "math",
# then assign it to a local variable called math.
math = __import__("math")
It prints the string
"before functionA"
.It executes the
def
block, creating a function object, then assigning that function object to a variable calledfunctionA
.It prints the string
"before functionB"
.It executes the second
def
block, creating another function object, then assigning it to a variable calledfunctionB
.It prints the string
"before __name__ guard"
.
Only When Your Module Is the Main Program
- If your module is the main program, then it will see that
__name__
was indeed set to"__main__"
and it calls the two functions, printing the strings"Function A"
and"Function B 10.0"
.
Only When Your Module Is Imported by Another
- (instead) If your module is not the main program but was imported by another one, then
__name__
will be"foo"
, not"__main__"
, and it'll skip the body of theif
statement.
Always
- It will print the string
"after __name__ guard"
in both situations.
Summary
In summary, here's what'd be printed in the two cases:
# What gets printed if foo is the main program
before import
before functionA
before functionB
before __name__ guard
Function A
Function B 10.0
after __name__ guard
# What gets printed if foo is imported as a regular module
before import
before functionA
before functionB
before __name__ guard
after __name__ guard
Why Does It Work This Way?
You might naturally wonder why anybody would want this. Well, sometimes you want to write a .py
file that can be both used by other programs and/or modules as a module, and can also be run as the main program itself. Examples:
Your module is a library, but you want to have a script mode where it runs some unit tests or a demo.
Your module is only used as a main program, but it has some unit tests, and the testing framework works by importing
.py
files like your script and running special test functions. You don't want it to try running the script just because it's importing the module.Your module is mostly used as a main program, but it also provides a programmer-friendly API for advanced users.
Beyond those examples, it's elegant that running a script in Python is just setting up a few magic variables and importing the script. "Running" the script is a side effect of importing the script's module.
Food for Thought
Question: Can I have multiple
__name__
checking blocks? Answer: it's strange to do so, but the language won't stop you.Suppose the following is in
foo2.py
. What happens if you saypython foo2.py
on the command-line? Why?
# Suppose this is foo2.py.
import os, sys; sys.path.insert(0, os.path.dirname(__file__)) # needed for some interpreters
def functionA():
print("a1")
from foo2 import functionB
print("a2")
functionB()
print("a3")
def functionB():
print("b")
print("t1")
if __name__ == "__main__":
print("m1")
functionA()
print("m2")
print("t2")
- Now, figure out what will happen if you remove the
__name__
check infoo3.py
:
# Suppose this is foo3.py.
import os, sys; sys.path.insert(0, os.path.dirname(__file__)) # needed for some interpreters
def functionA():
print("a1")
from foo3 import functionB
print("a2")
functionB()
print("a3")
def functionB():
print("b")
print("t1")
print("m1")
functionA()
print("m2")
print("t2")
- What will this do when used as a script? When imported as a module?
# Suppose this is in foo4.py
__name__ = "__main__"
def bar():
print("bar")
print("before __name__ guard")
if __name__ == "__main__":
bar()
print("after __name__ guard")
When your script is run by passing it as a command to the Python interpreter,
python myscript.py
all of the code that is at indentation level 0 gets executed. Functions and classes that are defined are, well, defined, but none of their code gets run. Unlike other languages, there's no main()
function that gets run automatically - the main()
function is implicitly all the code at the top level.
In this case, the top-level code is an if
block. __name__
is a built-in variable which evaluates to the name of the current module. However, if a module is being run directly (as in myscript.py
above), then __name__
instead is set to the string "__main__"
. Thus, you can test whether your script is being run directly or being imported by something else by testing
if __name__ == "__main__":
...
If your script is being imported into another module, its various function and class definitions will be imported and its top-level code will be executed, but the code in the then-body of the if
clause above won't get run as the condition is not met. As a basic example, consider the following two scripts:
# file one.py
def func():
print("func() in one.py")
print("top-level in one.py")
if __name__ == "__main__":
print("one.py is being run directly")
else:
print("one.py is being imported into another module")
# file two.py
import one
print("top-level in two.py")
one.func()
if __name__ == "__main__":
print("two.py is being run directly")
else:
print("two.py is being imported into another module")
Now, if you invoke the interpreter as
python one.py
The output will be
top-level in one.py
one.py is being run directly
If you run two.py
instead:
python two.py
You get
top-level in one.py
one.py is being imported into another module
top-level in two.py
func() in one.py
two.py is being run directly
Thus, when module one
gets loaded, its __name__
equals "one"
instead of "__main__"
.
The simplest explanation for the __name__
variable (imho) is the following:
Create the following files.
# a.py
import b
and
# b.py
print "Hello World from %s!" % __name__
if __name__ == '__main__':
print "Hello World again from %s!" % __name__
Running them will get you this output:
$ python a.py
Hello World from b!
As you can see, when a module is imported, Python sets globals()['__name__']
in this module to the module's name. Also, upon import all the code in the module is being run. As the if
statement evaluates to False
this part is not executed.
$ python b.py
Hello World from __main__!
Hello World again from __main__!
As you can see, when a file is executed, Python sets globals()['__name__']
in this file to "__main__"
. This time, the if
statement evaluates to True
and is being run.