pythonnamespacesprogram-entry-pointpython-moduleidioms

What does if __name__ == "__main__": do?


What does this do, and why should one include the if statement?

if __name__ == "__main__":
    print("Hello, World!")

If you are trying to close a question where someone should be using this idiom and isn't, consider closing as a duplicate of Why is Python running my module when I import it, and how do I stop it? instead. For questions where someone simply hasn't called any functions, or incorrectly expects a function named main to be used as an entry point automatically, use Why doesn't the main() function run when I start a Python script? Where does the script start running?.


Solution

  • Short Answer

    It's boilerplate code that protects users from accidentally invoking the script when they didn't intend to. Here are some common problems when the guard is omitted from a script:

    Long Answer

    To better understand why and how this matters, we need to take a step back to understand how Python initializes scripts and how this interacts with its module import mechanism.

    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.

    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 function_a")
    def function_a():
        print("Function A")
    
    print("before function_b")
    def function_b():
        print("Function B {}".format(math.sqrt(100)))
    
    print("before __name__ guard")
    if __name__ == '__main__':
        function_a()
        function_b()
    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

    1. It prints the string "before import" (without quotes).

    2. It loads the math module and assigns it to a variable called math. This is equivalent to replacing import 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")
    
    1. It prints the string "before function_a".

    2. It executes the def block, creating a function object, then assigning that function object to a variable called function_a.

    3. It prints the string "before function_b".

    4. It executes the second def block, creating another function object, then assigning it to a variable called function_b.

    5. It prints the string "before __name__ guard".

    Only When Your Module Is the Main Program

    1. 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

    1. (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 the if statement.

    Always

    1. 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 function_a
    before function_b
    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 function_a
    before function_b
    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:

    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

    # Suppose this is foo2.py.
    import os, sys; sys.path.insert(0, os.path.dirname(__file__)) # needed for some interpreters
    
    def function_a():
        print("a1")
        from foo2 import function_b
        print("a2")
        function_b()
        print("a3")
    
    def function_b():
        print("b")
    
    print("t1")
    if __name__ == "__main__":
        print("m1")
        function_a()
        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 function_a():
        print("a1")
        from foo3 import function_b
        print("a2")
        function_b()
        print("a3")
    
    def function_b():
        print("b")
    
    print("t1")
    print("m1")
    function_a()
    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")