meaning of if __name__ == “__main__”

Python Programming

Question or problem about Python programming:

Given the following code, what does the if __name__ == “__main__”: do?

# Threading example
import time, thread

def myfunction(string, sleeptime, lock, *args):
    while True:
        lock.acquire()
        time.sleep(sleeptime)
        lock.release()
        time.sleep(sleeptime)

if __name__ == "__main__":
    lock = thread.allocate_lock()
    thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
    thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))

How to solve the problem:

Solution 1:

Whenever the Python interpreter reads a source file, it does two things:

Let’s see how this works and how it relates to your question about the __name__ checks we always see in Python scripts.

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")

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"

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

# Find and load a module given its string name, "math",
# then assign it to a local variable called math.
math = __import__("math")

Only When Your Module Is the Main Program

Only When Your Module Is Imported by Another

Always

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

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:

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.

# 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")
      
# 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")
# Suppose this is in foo4.py
__name__ = "__main__"

def bar():
    print("bar")
    
print("before __name__ guard")
if __name__ == "__main__":
    bar()
print("after __name__ guard")

Solution 2:

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__”.

Solution 3:

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.

Solution 4:

To outline the basics:

Why do we need this?

Say you’re writing a Python script designed to be used as a module:

def do_important():
    """This function does something very important"""

You could test the module by adding this call of the function to the bottom:

do_important()

and running it (on a command prompt) with something like:

~$ python important.py

However, if you want to import the module to another script:

import important

On import, the do_important function would be called, so you’d probably comment out your function call, do_important(), at the bottom.

# do_important() # I must remember to uncomment to execute this!

And then you’ll have to remember whether or not you’ve commented out your test function call. And this extra complexity would mean you’re likely to forget, making your development process more troublesome.

The __name__ variable points to the namespace wherever the Python interpreter happens to be at the moment.

Inside an imported module, it’s the name of that module.

But inside the primary module (or an interactive Python session, i.e. the interpreter’s Read, Eval, Print Loop, or REPL) you are running everything from its “__main__”.

So if you check before executing:

if __name__ == "__main__":
    do_important()

With the above, your code will only execute when you’re running it as the primary module (or intentionally call it from another script).

There’s a Pythonic way to improve on this, though.

What if we want to run this business process from outside the module?

If we put the code we want to exercise as we develop and test in a function like this and then do our check for ‘__main__’ immediately after:

def main():
    """business logic for when running this module as the primary one!"""
    setup()
    foo = do_important()
    bar = do_even_more_important(foo)
    for baz in bar:
        do_super_important(baz)
    teardown()

# Here's our payoff idiom!
if __name__ == '__main__':
    main()

We now have a final function for the end of our module that will run if we run the module as the primary module.

It will allow the module and its functions and classes to be imported into other scripts without running the main function, and will also allow the module (and its functions and classes) to be called when running from a different ‘__main__’ module, i.e.

import important
important.main()

This idiom can also be found in the Python documentation in an explanation of the __main__ module. That text states:

Solution 5:

if __name__ == “__main__” is the part that runs when the script is run from (say) the command line using a command like python myscript.py.

Hope this helps!