Что такое __main__.py?

326

Для чего нужен __main__.pyфайл, какой код я должен в него вставить и когда он мне нужен?

Моника Сулик
источник

Ответы:

320

Часто программа на Python запускается путем именования файла .py в командной строке:

$ python my_program.py

Вы также можете создать каталог или zip-файл, полный кода, и включить __main__.py. Затем вы можете просто назвать каталог или zipfile в командной строке, и он __main__.pyавтоматически выполнит :

$ python my_program_dir
$ python my_program.zip
# Or, if the program is accessible as a module
$ python -m my_program

Вы должны решить для себя, может ли ваше приложение получить выгоду от такого выполнения.


Обратите внимание, что __main__ модуль обычно не приходит из __main__.pyфайла. Может, но обычно нет. Когда вы запускаете скрипт как python my_program.py, скрипт будет работать как __main__модуль, а не как my_programмодуль. Это также происходит для модулей, запущенных как python -m my_moduleили несколькими другими способами.

Если вы увидели имя __main__в сообщении об ошибке, это не обязательно означает, что вы должны искать __main__.pyфайл.

Нед Бэтчелдер
источник
22
Я обнаружил python -m program_dirи python program_dirнемного другое: последний никогда не запускается __init__.pyв каталоге (если он есть).
битый
5
@brk: Сейчас это не так. Я просто попытался, python3 program_dirи он побежал __init__.py.
Mk12
@ mk12 Я только что попробовал, я могу подтвердить выводы @ brk: python3 dirработает, __main__.pyно нет __init__.py, тогда как python3 -m dirработает оба.
Марчелло Романи
1
@ mk12 Вероятно, у вас был какой-то код, внутри __main__.pyкоторого был запущен импорт__init__.py
wim
100

Для чего нужен __main__.pyфайл?

При создании модуля Python модуль обычно выполняет некоторые функции (обычно содержащиеся в mainфункции) при запуске в качестве точки входа в программу. Обычно это делается с помощью следующей распространенной идиомы, расположенной внизу большинства файлов Python:

if __name__ == '__main__':
    # execute only if run as the entry point into the program
    main()

Вы можете получить ту же семантику для пакета Python с __main__.py. Это приглашение оболочки Linux, $если у вас нет Bash (или другой оболочки Posix) в Windows, просто создайте эти файлы demo/__<init/main>__.pyс содержимым между EOFs:

$ mkdir demo
$ cat > demo/__init__.py << EOF
print('demo/__init__.py executed')
def main():
    print('main executed')
EOF
$ cat > demo/__main__.py << EOF
print('demo/__main__.py executed')
from __init__ import main
main()
EOF

(В оболочке Posix / Bash вы можете сделать вышеупомянутое без << EOFs и заканчивая EOFs, введя Ctrl+ D, символ конца файла, в конце каждой команды cat)

И сейчас:

$ python demo
demo/__main__.py executed
demo/__init__.py executed
main executed

Вы можете получить это из документации. Документация говорит:

__main__ - Сценарий верхнего уровня

'__main__'Имя области, в которой выполняется код верхнего уровня. Модуль __name__устанавливается равным '__main__'при чтении из стандартного ввода, сценария или из интерактивного приглашения.

Модуль может выяснить, работает ли он в основной области, проверяя свою собственную __name__, что позволяет использовать общую идиому для условного выполнения кода в модуле, когда он запускается как скрипт или с ним, python -mно не при его импорте:

if __name__ == '__main__':
      # execute only if run as a script
      main()

Для пакета такой же эффект может быть достигнут путем включения __main__.pyмодуля, содержимое которого будет выполняться при запуске модуля -m.

Сжатые

Вы также можете упаковать это в один файл и запустить его из командной строки, как показано ниже, но обратите внимание, что заархивированные пакеты не могут выполнять подпакеты или подмодули в качестве точки входа:

$ python -m zipfile -c demo.zip demo/*
$ python demo.zip
demo/__main__.py executed
demo/__init__.py executed
main() executed
Аарон Холл
источник
31

__main__.pyиспользуется для программ на python в zip-файлах __main__.pyФайл будет выполнен , когда почтовый файл в запуске. Например, если zip-файл был таким:

test.zip
     __main__.py

и содержание __main__.pyбыло

import sys
print "hello %s" % sys.argv[1]

Тогда, если бы мы бежали, python test.zip worldмы бы получилиhello world вышли.

Таким образом, __main__.pyфайл запускается, когда python вызывается в zip-файле.

Синий перец
источник
23

Вы создаете __main__.pyв , yourpackageчтобы сделать его исполняемым , как:

$ python -m yourpackage
анатолий техтоник
источник
1
-mработает, если только программа доступна в виде модуля, иначе вы можете использовать python <yourpackage>ПРИМЕЧАНИЕ: без -mопции
Беньямин Джафари
1
@BenyaminJafari невозможно написать программу Python для командной строки, которая недоступна как модуль . Может ты имел ввиду package?
анатолий техтоник
1
Когда мы создаем пакет Python, который содержит основной .py, запускать его python -m <yourproject>не работает, -mэто избыточный вариант, но python <yourpackage>работает хорошо.
Беньямин Джафари
@BenyaminJafari В некоторых случаях флаг -m имеет значение. Выполнение из каталога aи допущение, что скрипт a/b/c/__main__.py... python -m b.cбудет выполняться из каталога, aи основной импорт скрипта будет относительным a. Но python b/cбудет выполняться из области импорта dir, cпоэтому любой импорт, такой как в основном скрипте, import b.dбудет неудачным.
MikeCPT
14

Если ваш скрипт представляет собой каталог или ZIP-файл, а не один файл Python, __main__.pyон будет выполнен, когда «скрипт» будет передан в качестве аргумента интерпретатору Python.

Wooble
источник