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.