Условный блок, начинающийся с 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”.