This article will show you the best way to handle “main” functions in Python.
Python is like a scripting language in that all lines in a Python “module” (a .py file) are executed whenever the file is run. Modules don’t need a “main” function. Consider a module named stuff.py with the following code:
def print_stuff():
print("stuff happened!")
print_stuff()
This is the output when it is run:
$ python stuff.py
stuff happened!
The print_stuff function was called as a regular line of code, not in any function. When the module ran, this line was executed.
This will cause a problem, though, if stuff is imported by another module. Consider a second module named more_stuff.py:
import stuff
stuff.print_stuff()
print("more stuff!")
At first glance, we may expect to see two lines printed. However, running more_stuff actually prints three lines:
$ python more_stuff.py
stuff happened!
stuff happened!
more stuff!
Why did “stuff happened!” get printed twice? Well, when “import stuff” was called, the stuff module was loaded. Whenever a module is loaded, all of its code is executed. The print_stuff function was called at line 4 in the stuff module. Then, it was called again at line 3 in the more_stuff module.
So, how can we avoid this problem? Simple: check the module’s __name__. The __name__ variable (pronounced “dunder name”) is dynamically set to the module’s name. If the module is the main entry point, then __name__ will be set to “__main__”. Otherwise, if the module is simply imported, then it will be set to the module’s filename without the “.py” extension.
Let’s rewrite our modules. Here’s stuff:
def print_stuff():
print("stuff happened!")
if __name__ == '__main__':
print_stuff()
And here’s more_stuff:
import stuff
if __name__ == '__main__':
stuff.print_stuff()
print("more stuff!")
If we rerun more_stuff, then the line “stuff happened!” will print only once:
$ python more_stuff.py
stuff happened!
more stuff!
As a best programming practice, Python modules should not contain any directly-called lines. They should contain only functions, classes, and variable initializations. Anything to be executed as a “main” body should be done after a check for “if __name__ == ‘__main__'”. That way, no rogue calls are made when modules are imported by other modules. The conditional check for __name__ also makes the “main” body clear to the reader.
Some people still like to have a “main” function. That’s cool. Just do it like this:
import stuff
def main():
stuff.print_stuff()
print("more stuff!")
if __name__ == '__main__':
main()
For more information, read this Stack Overflow article:
What does if __name__ == “__main__”: do?
One comment