Разделы портала

Онлайн-тренинги

.
Функция "main" в Python
02.04.2020 01:00

Автор: Энди Найт (Andy Knight)
Оригинал статьи
Перевод: Ольга Алифанова

Эта статья покажет вам наилучший способ обращения с Python-функциями "main".

Python похож на скриптовый язык: все строки в "модуле" Python (файле .py) выполняются всегда, когда этот файл запускается. Модулям не нужна функция main. Допустим, у нас есть модуль по имени stuff.py вот с каким кодом:

1

2

3

4

def print_stuff():

print("stuff happened!")


print_stuff()

Вот ее результат после запуска:

$ python stuff.py

stuff happened!

Функция print_stuff была вызвана как обычная строчка кода, а не в функции. Когда модуль был запущен, строчка была исполнена.

Однако это вызовет проблему, если stuff импортируется другим модулем. Допустим, у нас есть второй модуль по имени more_stuff.py:

1

2

3

4

import stuff


stuff.print_stuff()

print("more stuff!")

На первый взгляд мы ожидаем двух выведенных строк. Однако запуск more_stuff на самом деле выведет три строки:

$ python more_stuff.py

stuff happened!

stuff happened!

more stuff!

Почему строка “stuff happened!” выведена дважды? При вызове “import stuff” модуль stuff был загружен. Когда модуль загружается, выполняется весь его код. Функция print_stuff была вызвана в 4 строчке модуля stuff. Затем она была вызвана вновь в третьей строчке модуля more_stuff.

Как избежать этой проблемы? Легко: проверьте __name__ модуля. Переменная __name__.(произносится как "dunder name") динамически устанавливается как имя модуля. Если модуль – основная точка входа, то __name__. Будет задана как “__main__”. В прочих случаях, если модуль просто импортируется, она будет задана как имя файла модуля без расширения .py.

Давайте перепишем наши модули. Вот stuff:

1

2

3

4

5

def print_stuff():

print("stuff happened!")


if __name__ == '__main__':

print_stuff()

А вот more_stuff:

1

2

3

4

5

import stuff


if __name__ == '__main__':

stuff.print_stuff()

print("more stuff!")

Если мы перезапустим more_stuff, то строчка “stuff happened!” будет выведена только один раз:

$ python more_stuff.py

stuff happened!

more stuff!

Хорошая практика программирования модулей Python: они не должны содержать напрямую вызываемых строк. Они должны содержать только функции, классы, и инициализацию переменных. Все выполняемое как тело "main" должно выполняться после проверки на “if __name__ == ‘__main__'”. В этом случае при импортировании модуля другим модулем никаких инородных вызовов не произойдет. Условная проверка на __name__ также делает тело "main" понятнее для читателя.

Некоторым все равно нравится иметь функцию "main". Ну ок. Делайте это так:

1

2

3

4

5

6

7

8

import stuff


def main():

stuff.print_stuff()

print("more stuff!")


if __name__ == '__main__':

main()

Чтобы узнать больше, прочитайте эту статью на Stack Overflow: What does if __name__ == “__main__”: do?

Обсудить в форуме