Условный блок, начинающийся с if __name__ == "__main__" часто встречается в коде Python. Эта строка может выглядеть загадочно, и многие новички используют ее, не зная, что она делает и стоит ли ее использовать. Программисты, перешедшие на Python с других языков, также могут неправильно понимать эту идиому и использовать ее там, где это не нужно.
Из этой статьи вы узнаете о значении идиомы if__name__ == "__main__" в Python, а также о том, как и когда ее следует использовать.
Содержание
- Разбираемся, что такое __name__ и «__main__»
- Условный блок if __name__ == «__main__»
- Лучшие практики и советы по использованию if __name__ == «__main__»
- Заключение
Разбираемся, что такое __name__ и «__main__»
Идиома if __name__ == "__main__" — это оператор if, который проверяет равенство.
Первым операндом, стоящим слева от оператора равенства ==, является атрибут __name__. В Python имена, начинающиеся с двойного подчеркивания, являются специальными идентификаторами. Атрибут __name__ есть у каждого модуля. Python устанавливает в качестве значения этой переменной имя модуля, которое система импорта Python использует для уникальной идентификации каждого модуля.
Но если модуль находится в среде кода верхнего уровня, то есть является модулем, используемым в качестве точки входа в программу, Python устанавливает в качестве значения атрибута __name__ строку "__main__".
Давайте рассмотрим несколько примеров. Создадим скрипт под названием exploring_name_main.py:
# exploring_name_main.py import random print(__name__) print(random.__name__)
Этот скрипт можно запустить напрямую с помощью следующей команды в терминале:
$ python exploring_name_main.py
Вывод:
__main__ random
Скрипт exploring_name_main.py находится в среде кода верхнего уровня, так как является точкой входа в программу. Поэтому переменная __name__ установлена в строку "__main__".
Однако модуль random импортирован и не находится в среде кода верхнего уровня. Его атрибут __name__ устанавливается в имя модуля.
Далее мы создаем новый скрипт more_exploration.py, который импортирует первый скрипт:
# more_exploration.py import exploring_name_main
Запустите этот скрипт с помощью следующей команды в терминале:
$ python more_exploration.py
Вывод:
exploring_name_main random
Код модуля выполняется, когда модуль импортируется. Поэтому при запуске more_exploration.py код отображает вывод двух вызовов print() в exploring_name_main.py. Поскольку exploring_name_main.py больше не является точкой входа в программу, его атрибут __name__ устанавливается в имя скрипта вместо "__main__".
Условный блок if __name__ == «__main__»
Переменная __name__ может использоваться для определения того, является ли модуль главной точкой входа в программу. Таким образом, модуль может содержать код, который будет выполняться только при непосредственном запуске в качестве скрипта, но не при импорте. Любой код, который должен выполняться только при непосредственном запуске скрипта, включается в условный блок if __name__ == "__main__":
# 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}")
Код в exploring_name_main.py теперь включает условный блок if __name__ == "__main__". Давайте посмотрим, повлияет ли это на что-нибудь при выполнении скрипта:
$ python exploring_name_main.py
Вывод:
__main__ random This script is in the top-level code environment The number is 10
При непосредственном запуске скрипта переменная __name__ устанавливается в строку "__main__". Поэтому условие в операторе if оценивается как True, и Python выполняет код в блоке if.
Однако, когда модуль импортируется, __name__ устанавливается в имя модуля, и программа не выполняет блок if. Вспомните, что скрипт more_exploration.py импортирует exploring_name_main:
$ python more_exploration.py
Вывод:
exploring_name_main random
Программа не вызывает функции print() в exploring_name_main.py. Они находятся в условном блоке, который не выполняется, поскольку __name__ не равно "__main__".
Лучшие практики и советы по использованию if __name__ == «__main__»
Идиома Python if __name__ == "__main__" используется, если код должен выполняться только тогда, когда файл запускается как скрипт, а не импортируется как модуль. Различие между терминами «скрипт» и «модуль» заключается только в том, как используется файл. Оба термина относятся к файлам с расширением .py.
Чаще всего скрипт содержит переменные, функции и классы, которые могут использоваться в других программах. Вот пример использования скрипта с именем 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
Этот код не нуждается в идиоме if __name__ == "__main__", если предполагается всегда запускать его как скрипт. Однако включение этого условного оператора позволяет импортировать код как модуль без выполнения строк в блоке if.
Рассмотрим другой скрипт с именем 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
Этот новый скрипт, more_shapes.py, имеет доступ к функциям, определенным в shapes.py, благодаря оператору import. Однако код в блоке if __name__ == "__main__" в shapes.py не выполняется. Без оператора if в shapes.py при импорте модуля выполнялся бы весь код.
Блок if __name__ == "__main__" часто используется для пользовательского ввода. Пользовательский ввод опускается, если файл импортируется как модуль, но включается, если выполняется непосредственно как код верхнего уровня.
Использование функции main()
Лучше всего включать в блок if __name__ == "__main__" как можно меньше инструкций, так как это делает код более читабельным. Обычный способ добиться этого — создать функцию, которая вызывается в условном блоке. Обычно эта функция называется main(), но можно использовать любое имя:
# 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()
Код в функции main() — это тот же код, который был включен непосредственно в блок if __name__ == "__main__" в предыдущей версии кода.
В Python функция main() не требуется в качестве основной точки входа в программу, в отличие от некоторых других языков программирования. Поэтому использование функции main() и идиомы if __name__ == "__main__" необязательно, и нужно только в том случае, если код предполагается использовать и как отдельный скрипт, и как модуль.
Еще один распространенный случай использования if __name__ == "__main__" в Python — это включение тестов в скрипт. Тесты будут выполняться при непосредственном выполнении скрипта, но не при его импорте из другого модуля. Однако, хотя такой способ подходит для простых случаев, лучше включать тесты в отдельный модуль, предназначенный для тестирования.
Заключение
Идиома Python if __name__ == "__main__" полезна для включения кода, который выполняется только при непосредственном запуске скрипта, но не при его импорте. Интерпретатор Python устанавливает переменную __name__ в имя модуля, если он импортирован, и в строку "__main__", если модуль является основной точкой входа в программу.
В отличие от некоторых других языков программирования, функция main() и идиома if __name__ == "__main__" не являются обязательным условием для выполнения кода Python, но это инструмент, который программист может использовать, когда это необходимо.
Перевод статьи “if __name__ == «__main__» Python: Complete Explanation”.

