Track
The conditional block starting with if __name__ == "__main__"
appears often in Python code. This line can look cryptic, and many beginners use it without knowing what it does or whether they should be using it. Programmers coming from other languages can also misunderstand and overuse this idiom.
This tutorial dives into the meaning of Python's if__name__ == "__main__"
idiom and explores how and when to use it.
Become a Data Engineer
Understanding __name__
and "__main__"
The idiom if __name__ == "__main__"
is an if
statement that checks for equality.
The first operand on the left of the equality operator ==
is the attribute __name__
. Python names with leading and trailing double underscores are special identifiers. Every module has a __name__
attribute. Python sets this variable to the module name, which Python's import system uses to identify each module uniquely.
However, if the module is in the top-level code environment, which means it's the module used as the entry point for the program, Python sets the attribute __name__
to the string "__main__"
.
Let's look at some examples. Let’s create a script called exploring_name_main.py
:
# exploring_name_main.py
import random
print(__name__)
print(random.__name__)
This script can be run directly using the following command in the terminal:
$ python exploring_name_main.py
__main__
random
The script exploring_name_main.py
is in the top-level code environment since it's the program's entry point. Therefore, the __name__
variable is set to the string "__main__"
.
However, the random
module is imported and isn't in the top-level code environment. Its __name__
attribute is set to the module's name.
Next, we create a new script called more_exploration.py
, which imports the first script:
# more_exploration.py
import exploring_name_main
Run this script using the following command in the terminal:
$ python more_exploration.py
exploring_name_main
random
A module's code is executed when the module is imported. Therefore, when running more_exploration.py
, the code displays the output from the two print()
calls in exploring_name_main.py
. Since exploring_name_main.py
is no longer the program's point of entry, its __name__
attribute is set to the script's name instead of "__main__"
.
The if __name__ == "__main__"
Conditional Block
The variable __name__
can be used to determine whether a module is the main entry point of a program. Therefore, a module can include code that's only executed when it's run directly as a script but not when it's imported. Any code that should only be executed when the script is run directly is included in the if __name__ == "__main__"
conditional block:
# exploring_name_main.py
import random
print(__name__)
print(random.__name__)
number = random.randint(1, 10)
if __name__ == "__main__":
print("This script is in the top-level code environment")
print(f"The number is {number}")
The code in exploring_name_main.py
now includes an if __name__ == "__main__"
conditional block. Let's see whether this makes a difference when running the script:
$ python exploring_name_main.py
__main__
random
This script is in the top-level code environment
The number is 10
When the script is run directly, the variable __name__
is set to the string "__main__"
. Therefore, the condition in the if
statement evaluates as True
, and Python executes the code in the if
block.
However, when the module is imported, __name__
is set to the module's name, and the program doesn't execute the if
block. Recall that the script more_exploration.py
imports exploring_name_main
:
$ python more_exploration.py
exploring_name_main
random
The program doesn't call the print()
functions in exploring_name_main.py
. They're in the conditional block that isn't executed since __name__
is not equal to "__main__"
.
Best Practices and Tips When Using Python's if __name__ == "__main__"
Python's if __name__ == "__main__"
idiom is used when code should be executed only when a file is run as a script rather than imported as a module. The distinction between the terms script and module is only in how the file is used. Both terms refer to files with the .py
extension.
A common use case is when a script has variables, functions, and classes that may be used in other programs. Here's an example using a script named shapes.py
:
# shapes.py
import math
def find_area_of_circle(radius):
return math.pi * radius ** 2
def find_area_of_rectangle(width, height):
return width * height
if __name__ == "__main__":
shape = int(input("Enter 1 for circle, 2 for rectangle: "))
if shape == 1:
radius = int(input("Enter radius: "))
print(f"The area of the circle is {find_area_of_circle(radius)}")
elif shape == 2:
width = int(input("Enter width: "))
height = int(input("Enter height: "))
print(f"The area of the rectangle is {find_area_of_rectangle(width, height)}")
Enter 1 for circle, 2 for rectangle: 2
Enter width: 10
Enter height: 20
The area of the rectangle is 200
This code doesn't need the if __name__ == "__main__"
idiom if the intention is always to run it as a script. However, the inclusion of this conditional statement enables the code to be imported as a module without executing the lines in the if
block. Consider another script named more_shapes.py
:
# more_shapes.py
import shapes
radius = 5
print(f"The area of the circle defined in 'more_shapes.py' is: "
f"{shapes.find_area_of_circle(radius)}")
The area of the circle defined in 'more_shapes.py' is: 78.53981633974483
This new script, more_shapes.py
, has access to the functions defined in shapes.py
because of the import statement. However, the code in the if __name__ == "__main__"
block in shapes.py
isn't executed. Without the if
statement in shapes.py
, all the code would be executed when the module is imported.
Using the if __name__ == "__main__"
block for user input is a common use case. The user input is omitted if the file is imported as a module but is included when executed directly as top-level code.
Using a main()
function
It's best practice to include as few statements as possible in the if __name__ == "__main__"
block as this makes the code more readable. A common way of achieving this is to create a function, which is called in the conditional block. It's common for this function to be called main()
, but any function name is valid:
# shapes.py
import math
def find_area_of_circle(radius):
return math.pi * radius ** 2
def find_area_of_rectangle(width, height):
return width * height
def main():
shape = int(input("Enter 1 for circle, 2 for rectangle: "))
if shape == 1:
radius = int(input("Enter radius: "))
print(f"The area of the circle is {find_area_of_circle(radius)}")
elif shape == 2:
width = int(input("Enter width: "))
height = int(input("Enter height: "))
print(f"The area of the rectangle is {find_area_of_rectangle(width, height)}")
if __name__ == "__main__":
main()
The code in the main()
function is the same code that was included directly in the if __name__ == "__main__"
block in the earlier version of the code.
In Python, the main()
function is not required as the main entry point to the program, unlike some other programming languages. Therefore, the use of main()
and the if __name__ == "__main__"
idiom is optional, and it's only needed when the code is intended to be used both as a standalone script and as a module.
Another common use case for Python's if __name__ == "__main__"
is to include tests to the script. The tests will run when the script is executed directly but not when it's imported from another module. However, while this approach is suitable for simple cases, it's best to include tests in a separate module dedicated to testing.
Conclusion
Python's if __name__ == "__main__"
is useful to include code that's executed only when a script is run directly but not when it's imported. The Python interpreter sets the __name__
variable to the name of the module if it's imported and to the string "__main__"
if the module is the main entry point to the program.
Unlike in some other programming languages, the main()
function and the if __name__ == "__main__"
idiom is not a requirement to run Python code, but it's a tool the programmer can use when required.
Become a Data Engineer
I studied Physics and Mathematics at UG level at the University of Malta. Then, I moved to London and got my PhD in Physics from Imperial College. I worked on novel optical techniques to image the human retina. Now, I focus on writing about Python, communicating about Python, and teaching Python.