python 如何写好main函数

时间:2024-09-28 12:34:38

每个程序员在学习编程的过程中,肯定没少写过main()函数,Python程序员也不例外。本文为大家分享Python之父Guido van Rossum推荐的函数写法,可以大大提高这个函数的灵活性。

一般来说,Python程序员可能是这样写main()函数的:

"""Module docstring.

This serves as a long usage message.

"""

import sys

import getopt

def main():

# parse command line options

try:

opts, args = getopt.getopt(sys.argv[1:], "h", ["help"])

except getopt.error, msg:

print msg

print "for help use --help"

sys.exit(2)

# process options

for o, a in opts:

if o in ("-h", "--help"):

print __doc__

sys.exit(0)

# process arguments

for arg in args:

process(arg) # process() is defined elsewhere

if __name__ == "__main__":

main()

Guido也承认之前自己写的main()函数也是类似的结构,但是这样写的灵活性还不够高,尤其是需要解析复杂的命令行选项时。为此,他向大家提出了几点建议。

添加可选的 argv 参数

首先,修改main()函数,使其接受一个可选参数 argv,支持在交互式shell中调用该函数:

def main(argv=None):

if argv is None:

argv = sys.argv

# etc., replacing sys.argv with argv in the getopt() call.

这样做,我们就可以动态地提供 argv 的值,这比下面这样写更加的灵活:

def main(argv=sys.argv):

# etc.

这是因为在调用函数时,sys.argv 的值可能会发生变化;可选参数的默认值都是在定义main()函数时,就已经计算好的。

但是现在sys.exit()函数调用会产生问题:当main()函数调用sys.exit()时,交互式解释器就会推出!解决办法是让main()函数的返回值指示退出状态(exit status)。因此,最后面的那行代码就变成了这样:

if __name__ == "__main__":

sys.exit(main())

并且,main()函数中的sys.exit(n)调用全部变成return n。

定义一个Usage()异常

另一个改进之处,就是定义一个Usage()异常,可以在main()函数最后的except子句捕捉该异常:

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, msg:

raise Usage(msg)

# more code, unchanged

except Usage, err:

print >>sys.stderr, err.msg

print >>sys.stderr, "for help use --help"

return 2

if __name__ == "__main__":

sys.exit(main())

这样main()函数就只有一个退出点(exit)了,这比之前两个退出点的做法要好。而且,参数解析重构起来也更容易:在辅助函数中引发Usage的问题不大,但是使用return 2却要求仔细处理返回值传递的问题。

python 中name == ‘__main__’ 的作用

经典的英文解释:Make a script both importable and executable

中文解释:使脚本可以被调用import并且也可以直接运行

1、直接运行

# cat test_fun.py

def fun():

print(__name__)

print('this is fun')

if __name__ == '__main__':

fun()

print('this is main')

python test_fun.py

__main__

this is fun

this is main

2、被调用import

>>> import test_fun

>>> test_fun.fun()

test_fun

this is fun

调用导入时:此处输出没有显示”main“,也就是说模块name = ‘main’ 下面的代码并未执行,main函数没有执行。

这个功能还有一个用处:调试代码的时候,在”if name == ‘main‘“中加入一些我们的调试代码,我们可以让外部模块调用的时候不执行我们的调试代码,但是如果我们想排查问题的时候,直接执行该模块文件,调试代码能够正常运行!

python是一种解释型脚本语言,和C/C++语言不同,C/C++程序从main函数开始执行,python程序从开始到结尾顺序执行。先总结下python中的main函数的作用:让模块(函数)可以自己单独执行(调试),相当于构造了调用其它函数的入口,这就类似于C/C++里面的mian函数了。

一方面:我们想要自己单独执行(调试)

这里我们实际调试一下(假设这个文件是test.py):

#test.py

print('Hello World!')

def aaa():

print('this message is from aaa  function')

def main():

print('this message is from main function')

if __name__ == '__main__':

main()

print ('now __name__ is %s' %__name__)

执行python test.py  输出:

Hello World!

this message is from main function

now __name__ is __main__

这里我们看到我们定义的aaa函数没有被执行,而main函数里面的内容被执行了,表明 if __name__ == '__main__': 这条判断语句是通过的,执行了判断条件里的main();

另一方面:外汇返佣http://www.kaifx.cn/,通过import命令就可以使用其它.py文件里面的函数,我们将test.py中的模块(函数)导入call.py,需注意test.py和call.py放在同一个文件夹下;

#call.py

from test import aaa

aaa()

print ('now __name__ is %s' %__name__)

执行python  call.py  输出:

Hello World!

this message is from aaa  function

now __name__ is __main__

所以当我们自己写了.py文件,想要测试里面的函数时,就这样构造一个main函数入口就可以调用测试自己写的函数啦~