Прежде чем что-либо объяснять о if __name__ == '__main__'
, важно понять, что такое __name__
и что оно делает.
Что такое __name__
?
__name__
- это DunderAlias - может рассматриваться как глобальная переменная (доступная из модулей) и работает аналогично global
.
Это строка (глобальная, как упоминалось выше), обозначенная type(__name__)
(получая <class 'str'>
), и является встроенным стандартом для Python 3 и Python 2 версии.
Где:
Его можно использовать не только в скриптах, но и в интерпретаторе, и в модулях / пакетах.
Переводчик:
>>> print(__name__)
__main__
>>>
Сценарий:
test_file.py
print(__name__)
В результате __main__
Модуль или упаковка:
somefile.py:
def somefunction():
print(__name__)
test_file.py:
import somefile
somefile.somefunction()
В результате somefile
Обратите внимание, что при использовании в пакете или модуле __name__
принимает имя файла. Путь к действительному модулю или пути пакета не указан, но имеет свой собственный DunderAlias __file__
, который учитывает это.
Вы должны увидеть, что, где __name__
, где находится основной файл (или программа), будет всегда возвращать __main__
, и если это модуль / пакет, или что-либо, что работает от какого-либо другого скрипта Python, вернет имя файла, из которого он произошел.
Практика:
Если переменная означает, что ее значение может быть перезаписано («может» не означает «следует»), перезапись значения __name__
приведет к недостаточной читаемости. Так что не делай этого ни по какой причине. Если вам нужна переменная, определите новую переменную.
Всегда предполагается, что значением __name__
будет __main__
или именем файла. Повторное изменение этого значения по умолчанию вызовет еще большую путаницу в том, что оно пойдет на пользу, и вызовет проблемы в дальнейшем.
пример:
>>> __name__ = 'Horrify' # Change default from __main__
>>> if __name__ == 'Horrify': print(__name__)
...
>>> else: print('Not Horrify')
...
Horrify
>>>
В целом считается хорошей практикой включать if __name__ == '__main__'
в сценарии.
Теперь, чтобы ответить if __name__ == '__main__'
:
Теперь мы знаем, как поведение __name__
становится понятнее:
if
- это оператор управления потоком, который содержит блок кода, который будет выполняться, если заданное значение равно true. Мы видели, что __name__
может принимать либо
__main__
или имя файла, из которого оно было импортировано.
Это означает, что если __name__
равно __main__
, то этот файл должен быть основным файлом и фактически должен быть запущен (или интерпретатором), а не модулем или пакетом, импортированным в сценарий.
Если действительно __name__
принимает значение __main__
, то все, что находится в этом блоке кода, будет выполняться.
Это говорит нам о том, что если выполняемый файл является основным файлом (или вы запускаете непосредственно из интерпретатора), то это условие должно выполняться. Если это пакет, то не должен, и значение не будет __main__
.
Модули:
__name__
также может использоваться в модулях для определения имени модуля
Варианты:
Можно также делать другие, менее распространенные, но полезные вещи с __name__
, некоторые я покажу здесь:
Выполняется, только если файл является модулем или пакетом:
if __name__ != '__main__':
# Do some useful things
Запуск одного условия, если файл является основным, и другого, если это не так:
if __name__ == '__main__':
# Execute something
else:
# Do some useful things
Вы также можете использовать его для обеспечения работоспособных функций / утилит справки для пакетов и модулей без тщательного использования библиотек.
Он также позволяет запускать модули из командной строки в качестве основных сценариев, что также может быть очень полезно.