1. 程式人生 > >sys.exit(main(sys.argv[1:]))

sys.exit(main(sys.argv[1:]))

字符串 推出 quit n) 操作 可能 接口 在線 html

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.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

sys.exit(main(sys.argv[1:]))