sys.argv
sys.argv[]说白了就是一个从程序外部获取参数的桥梁。
首先我们需要import sys,sys是python3的一个标准库,也就是一个官方的模块。封装了一些系统的信息和接口,然后再说说argv这个变量。「argv」是「argument variable」参数变量的简写形式,一般在命令行调用的时候由系统传递给程序。因为我们从外部取得的参数可以是多个,所以获得的是一个列表(list),也就是说sys.argv其实可以看作是一个列表,所以才能用[]提取其中的元素。其第一个元素是程序本身,即sys.argv[0]是当前所执行的脚本,index 1以后的才是所传入的参数,用sys.argv[1:]可以获取到所有的参数,并且输出到一个列表里面。而切片获取的参数类型为字符串,即sys.argv传入的参数为字符串类型,如果想做一些条件判断的话需要转成所需要的数据类型。
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()
这样写的灵活性还不够高,尤其是需要解析复杂的命令行选项时。
添加可选的 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())
定义一个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
却要求仔细处理返回值传递的问题。
您可能会将try / except子句从main()函数移出到模块末尾的代码中(if__name__ ==“__ main__”:......)但这意味着 当你以交互方式调用main()时,但这会引发syntax errors,这不是很有用。
sys.exit() VS os._exit()
sys.exit(n)会引发一个异常:SystemExit,可以捕获异常执行些清理工作。此处用于捕获模块执行结果,如果这个异常没有被捕获,那么python解释器将会退出。如果有捕获此异常的代码,那么这些代码还是会执行。0为正常退出,其他数值(1-127)为不正常,可抛异常事件供捕获。sys.exit() 用于在主线程中退出。
python的程序有两中退出方式:os._exit(), sys.exit()。
os._exit()会直接将python程序终止,之后的所有代码都不会继续执行。即直接退出, 不抛异常, 不执行相关清理工作。
sys.exit()会引发一个异常:SystemExit,如果这个异常没有被捕获,那么python解释器将会退出。如果有捕获此异常的代码,那么这些代码还是会执行。
一般来说os._exit() 用于在线程中退出,sys.exit() 用于在主线程中退出。
import os try: os._exit(0) except: print("die")
不会打印“die”
try: sys.exit(0) except: print('die') finally: print('cleanup')
输出:
die
cleanup
区别
综上,sys.exit()的退出比较优雅,调用后会引发SystemExit异常,可以捕获此异常做清理工作。os._exit()直接将python解释器退出,余下的语句不会执行。
一般情况下使用sys.exit()即可,一般在fork出来的子进程中使用os._exit()。
此外,还有exit()/quit() ,exit()跟 C 语言等其他语言的 exit() 应该是一样的,抛出SystemExit异常。一般在交互式shell中退出时使用。
在很多类型的操作系统里,exit(0) 可以中断某个程序,而其中的数字参数则用来表示程序是否是碰到错误而中断。exit(1) 表示发生了错误,而 exit(0) 则表示程序是正常退出。
这和我们学的布尔逻辑 0==False 正好相反,不过你可以用不一样的数字表示不同的错误结果。比如你可以用exit(100) 来表示另一种和 exit(2)或 exit(1) 不同的错误。
【参考文档】
main函数使用sys.argv传入多个参数:https://blog.csdn.net/liao392781/article/details/80321614
python 如何写好main函数:http://codingpy.com/article/guido-shows-how-to-write-main-function/
原文Python main() functions:https://www.artima.com/weblogs/viewpost.jsp?thread=4829
os._exit() vs sys.exit():http://www.cnblogs.com/gaott/archive/2013/04/12/3016355.html
python中exit()的用法:https://blog.csdn.net/Jinger_Warrior/article/details/77628460