关于python:什么是__main__.py?

What is __main__.py?

__main__.py文件是用来做什么的,我应该把什么类型的代码放进去,什么时候应该有一个?


通常,通过在命令行中命名.py文件来运行python程序:

1
$ python my_program.py

您还可以创建一个包含代码的目录或压缩文件,并包括一个__main__.py。然后您可以在命令行上简单地命名目录或zipfile,它会自动执行__main__.py

1
2
3
4
$ 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文件。


__main__.py文件的用途是什么?

创建python模块时,通常让模块在作为程序入口点运行时执行一些功能(通常包含在main函数中)。这通常是通过在大多数python文件的底部放置以下常见的习惯用法来完成的:

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

对于使用__main__.py的python包,您可以获得相同的语义。这是一个Linux shell提示,$,如果Windows上没有bash(或其他posix shell),只需在demo/____.py上创建这些文件,内容在EOF之间:

1
2
3
4
5
6
7
8
9
10
11
$ 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 shell中,通过在每个cat命令末尾输入ctrl+d(文件结束字符),可以在不使用<< EOFs和结束EOF的情况下执行上述操作)

现在:

1
2
3
4
$ python demo
demo/__main__.py executed
demo/__init__.py executed
main executed

你可以从文档中得到这个。文件上说:

__main__ — Top-level script environment

'__main__' is the name of the scope in which top-level code executes.
A module’s __name__ is set equal to '__main__' when read from standard
input, a script, or from an interactive prompt.

A module can discover whether or not it is running in the main scope
by checking its own __name__, which allows a common idiom for
conditionally executing code in a module when it is run as a script or
with python -m but not when it is imported:

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

For a package, the same effect can be achieved by including a
__main__.py module, the contents of which will be executed when the module is run with -m.

拉链

您也可以将它打包成一个单独的文件,然后像这样从命令行运行它-但是请注意,压缩包不能作为入口点执行子包或子模块:

1
2
3
4
5
$ python -m zipfile -c demo.zip demo/*
$ python demo.zip
demo/__main__.py executed
demo/__init__.py executed
main() executed


__main__.py用于zip文件中的python程序。运行zip文件时将执行__main__.py文件。例如,如果zip文件是这样的:

1
2
test.zip
     __main__.py

其中__main__.py的含量为

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

然后,如果我们运行python test.zip world,我们将把hello world取出来。

因此,当对zip文件调用python时,__main__.py文件将运行。


yourpackage中创建__main__.py使其可执行为:

1
$ python -m yourpackage


如果脚本是目录或zip文件而不是单个python文件,则当"script"作为参数传递给python解释器时,将执行__main__.py