参考:https://lance.moe/post-301.html
if name== ‘main’: 判断是否为主程序。
直接运行py文件时,会运行if name== ‘main’:,如果是导入该py文件,不会运行。

作用

Python使用缩进来对代码组织并执行,所有没有缩进的代码(非函数定义、类定义),都会在载入时自动执行,这些代码,都可以认为是Python的main函数内的代码。

print('hello world!')

相当于

def main():
    print('hello world!')

main()

为了区分主执行文件还是被调用的文件,Python引入了一个变量__name__,
当文件是被调用时,__name__的值为模块名,
当文件被执行时,__name__为’main’。
这个特性,我们可以在每个模块中写上测试代码,这些测试代码仅当模块被Python直接执行时才会运行,代码和测试完美的结合在一起。
例如:

def main():
    print('hello world!')

if __name__ == '__main__':
    main()

这样做和上面的区别在哪里呢?
假如我们新建一个myclass.py,内容如下:

def main():
    print('main:hello world!')

if __name__ == '__main__':
    main()

print('hello world!')

直接运行代码,我们发现,输出结果为

main:hello world!
hello world!

然而,我们保存刚才的代码,在同目录新建一个test.py,内容如下

import myclass

会发现输出如下

hello world!

我们很容易发现,被定义在main函数中的print语句并没有执行,这其实就是main函数最重要的作用之一,防止代码被作为模块使用时,一句import直接影响了调用模块的程序。
(模块调用不会执行main函数内的print)

完善

其实main函数的作用不止于此,它还可以用来接收执行的参数。保存下面的文件为test.py

import sys
def main(argv=sys.argv):
    if argv == None:
        print('hello world!')
    else:
        print(argv)

if __name__ == '__main__':
    main()

假如我们在终端或命令提示符运行

>> python test.py -test -my

会发现程序可以输出

['test.py', '-test', '-my']

然而这样做还是有些小缺陷,这个程序在python的idle里,无法正常main函数传参数。

我们修改尝试main函数,使其接受一个可选参数 argv,这样它就支持在交互式shell中调用该函数

def main(argv=None):
    if argv is None:
        argv = sys.argv

但是现在sys.exit()函数调用会产生问题:当main函数调用sys.exit()时,交互式解释器就会崩溃退出!
解决办法是让main()函数的返回值指示退出状态(exit status)。
并且,main函数中的sys.exit(n)调用需要全部变成return n

if __name__ == "__main__":
    sys.exit(main())

另外,为了更加完善,可以定义Usage()异常。

Python之父Guido van Rossum提出了他自己在使用的模板,我将其改成了python3样式:

import sys
import getopt

class Usage(Exception):
    def __init__(self, msg):
        self.msg = msg
        
def main(argv=None):
    if argv is None:
        argv = sys.argv
    try:
        try:
            opts, args = getopt.getopt(argv[1:], "h", ["help"])
        except getopt.error as msg:
            raise Usage(msg)
        # more code, unchanged
    except Usage as err:
        print(sys.stderr, err.msg)
        print(sys.stderr, "for help use --help")
        return 2
if __name__ == "__main__":
    sys.exit(main())