您好,登錄后才能下訂單哦!
這篇 Python學習教程主要是對 argparse(Python標準庫中推薦的命令行解析模塊) 進行簡要介紹。
note 還有兩個其他模塊也可以完成相同的任務,分別是 getopt(與C語言中的 getopt() 等效)和已經過時的 optparse。需要注意的是 argparse 也是基于 optparse,因此在用法上非常相似。
概念
讓我們通過使用 ls 命令來展示我們將在本 Python學習教程入門中探索的功能類型:
$ ls cpython devguide prog.py pypy rm-unused-function.patch $ ls pypy ctypes_configure demo dotviewer include lib_pypy lib-python ... $ ls -l total 20 drwxr-xr-x 19 wena wena 4096 Feb 18 18:51 cpython drwxr-xr-x 4 wena wena 4096 Feb 8 12:04 devguide -rwxr-xr-x 1 wena wena 535 Feb 19 00:05 prog.py drwxr-xr-x 14 wena wena 4096 Feb 7 00:59 pypy -rw-r--r-- 1 wena wena 741 Feb 18 01:01 rm-unused-function.patch $ ls --help Usage: ls [OPTION]... [FILE]... List information about the FILEs (the current directory by default). Sort entries alphabetically if none of -cftuvSUX nor --sort is specified. ...
從這四個命令中我們可以學到一些概念:
基礎用法
讓我們從一個非常簡單的例子開始,這個例子幾乎什么事情都沒做:
import argparse parser = argparse.ArgumentParser() parser.parse_args()
下面是執行這段代碼的結果:
$ python3 prog.py $ python3 prog.py --help usage: prog.py [-h] optional arguments: -h, --help show this help message and exit $ python3 prog.py --verbose usage: prog.py [-h] prog.py: error: unrecognized arguments: --verbose $ python3 prog.py foo usage: prog.py [-h] prog.py: error: unrecognized arguments: foo
下面是這段代碼做了什么的解釋:
位置參數介紹
一個例子:
import argparse parser = argparse.ArgumentParser() parser.add_argument("echo") args = parser.parse_args() print(args.echo)
運行這段代碼:
import argparse parser = argparse.ArgumentParser() parser.add_argument("echo") args = parser.parse_args() print(args.echo)
代碼解釋:
然而請注意,盡管幫助信息看起來不錯,但目前并不是很有用。例如,我們看到了我們將 echo 作為了位置參數,但除了猜測和閱讀源代碼外,我們不知道它的作用。因此,讓我們將它變得更加有用:
import argparse parser = argparse.ArgumentParser() parser.add_argument("echo", help="echo the string you use here") args = parser.parse_args() print(args.echo)
這時我們將得到:
$ python3 prog.py -h usage: prog.py [-h] echo positional arguments: echo echo the string you use here optional arguments: -h, --help show this help message and exit
現在,讓我們來做一些更有用的事情:
import argparse parser = argparse.ArgumentParser() parser.add_argument("square", help="display a square of a given number") args = parser.parse_args() print(args.square**2)
上面代碼執行的結果如下:
$ python3 prog.py 4 Traceback (most recent call last): File "prog.py", line 5, in <module> print(args.square**2) TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'
結果不是很好,這是因為 argparse 將我們給的選項當成了字符串,除非我們手動指定類型。因此,讓我們來告訴 argparse 將它視為一個整數:
import argparse parser = argparse.ArgumentParser() parser.add_argument("square", help="display a square of a given number", type=int) args = parser.parse_args() print(args.square**2)
下面是上述代碼的執行結果:
$ python3 prog.py 4 16 $ python3 prog.py four usage: prog.py [-h] square prog.py: error: argument square: invalid int value: 'four'
結果很好,程序甚至可以在執行前因為錯誤輸入而結束。
可選參數介紹
到目前為止,我們已經介紹過了位置參數。接下來讓我們看下如何添加一個可選參數:
import argparse parser = argparse.ArgumentParser() parser.add_argument("--verbosity", help="increase output verbosity") args = parser.parse_args() if args.verbosity: print("verbosity turned on")
運行結果:
$ python3 prog.py --verbosity 1 verbosity turned on $ python3 prog.py $ python3 prog.py --help usage: prog.py [-h] [--verbosity VERBOSITY] optional arguments: -h, --help show this help message and exit --verbosity VERBOSITY increase output verbosity $ python3 prog.py --verbosity usage: prog.py [-h] [--verbosity VERBOSITY] prog.py: error: argument --verbosity: expected one argument
代碼解釋如下:
上面的例子對于 --verbosity 還可以接受任意整數,但對我們的程序來說,只有 True 和 False 是有用的。因此我們修改代碼如下:
import argparse parser = argparse.ArgumentParser() parser.add_argument("--verbose", help="increase output verbosity", action="store_true") args = parser.parse_args() if args.verbose: print("verbosity turned on")
結果如下:
python3 prog.py --verbose verbosity turned on $ python3 prog.py --verbose 1 usage: prog.py [-h] [--verbose] prog.py: error: unrecognized arguments: 1 $ python3 prog.py --help usage: prog.py [-h] [--verbose] optional arguments: -h, --help show this help message and exit --verbose increase output verbosity
代碼解釋如下:
短選項
如果你熟悉命令行的用法,你們發現目前為止我還沒有涉及這個選項的簡短版本的話題。下面是一個很簡單的示例:
import argparse parser = argparse.ArgumentParser() parser.add_argument("-v", "--verbose", help="increase output verbosity", action="store_true") args = parser.parse_args() if args.verbose: print("verbosity turned on")
執行結果如下:
$ python3 prog.py -v verbosity turned on $ python3 prog.py --help usage: prog.py [-h] [-v] optional arguments: -h, --help show this help message and exit -v, --verbose increase output verbosity
注意在幫助信息中反映了這個新的功能。
位置參數與可選參數的結合
我們的程序變得越來越復雜了:
import argparse parser = argparse.ArgumentParser() parser.add_argument("square", type=int, help="display a square of a given number") parser.add_argument("-v", "--verbose", action="store_true", help="increase output verbosity") args = parser.parse_args() answer = args.square**2 if args.verbose: print("the square of {} equals {}".format(args.square, answer)) else: print(answer)
輸出如下:
$ python3 prog.py usage: prog.py [-h] [-v] square prog.py: error: the following arguments are required: square $ python3 prog.py 4 16 $ python3 prog.py 4 --verbose the square of 4 equals 16 $ python3 prog.py --verbose 4 the square of 4 equals 16
我們如何讓我們這個程序具有多個 verbosity 值,并實際使用這些值:
import argparse parser = argparse.ArgumentParser() parser.add_argument("square", type=int, help="display a square of a given number") parser.add_argument("-v", "--verbosity", type=int, help="increase output verbosity") args = parser.parse_args() answer = args.square**2 if args.verbosity == 2: print("the square of {} equals {}".format(args.square, answer)) elif args.verbosity == 1: print("{}^2 == {}".format(args.square, answer)) else: print(answer)
輸出如下:
$ python3 prog.py 4 16 $ python3 prog.py 4 -v usage: prog.py [-h] [-v VERBOSITY] square prog.py: error: argument -v/--verbosity: expected one argument $ python3 prog.py 4 -v 1 4^2 == 16 $ python3 prog.py 4 -v 2 the square of 4 equals 16 $ python3 prog.py 4 -v 3 16
上面結果除了最后一個看上去都沒問題。最后一個暴露了我們程序的一個 bug。讓我們通過限制 verbosity 可接受的值來修復它:
import argparse parser = argparse.ArgumentParser() parser.add_argument("square", type=int, help="display a square of a given number") parser.add_argument("-v", "--verbosity", type=int, choices=[0, 1, 2], help="increase output verbosity") args = parser.parse_args() answer = args.square**2 if args.verbosity == 2: print("the square of {} equals {}".format(args.square, answer)) elif args.verbosity == 1: print("{}^2 == {}".format(args.square, answer)) else: print(answer)
輸出如下:
$ python3 prog.py 4 -v 3 usage: prog.py [-h] [-v {0,1,2}] square prog.py: error: argument -v/--verbosity: invalid choice: 3 (choose from 0, 1, 2) $ python3 prog.py 4 -h usage: prog.py [-h] [-v {0,1,2}] square positional arguments: square display a square of a given number optional arguments: -h, --help show this help message and exit -v {0,1,2}, --verbosity {0,1,2} increase output verbosity
需要注意的是,對應的改變在報錯信息和幫助信息中都有體現。
現在,讓我們用另外一種更通用的方式來使用 verbosity 選項。這種方式與 CPython 解釋器中處理 verbosity 選項相同(可通過 python --help 查看):
import argparse parser = argparse.ArgumentParser() parser.add_argument("square", type=int, help="display the square of a given number") parser.add_argument("-v", "--verbosity", action="count", help="increase output verbosity") args = parser.parse_args() answer = args.square**2 if args.verbosity == 2: print("the square of {} equals {}".format(args.square, answer)) elif args.verbosity == 1: print("{}^2 == {}".format(args.square, answer)) else: print(answer)
我們引入了另外一種 action:"count",它用于計算一個可選參數出現的次數:
$ python3 prog.py 4 16 $ python3 prog.py 4 -v 4^2 == 16 $ python3 prog.py 4 -vv the square of 4 equals 16 $ python3 prog.py 4 --verbosity --verbosity the square of 4 equals 16 $ python3 prog.py 4 -v 1 usage: prog.py [-h] [-v] square prog.py: error: unrecognized arguments: 1 $ python3 prog.py 4 -h usage: prog.py [-h] [-v] square positional arguments: square display a square of a given number optional arguments: -h, --help show this help message and exit -v, --verbosity increase output verbosity $ python3 prog.py 4 -vvv 16
是的,現在我們的腳本比之前的版本多了一個標識(類似于之前的 action="store_true")。可以在報錯信息中看到這一解釋。
它和 "store_action" 的作用類似。
這里是對 "count" 作用的證明。你可以在之前已經看到過這一個用法。
如果你不指定 -v 標識,這個標識被認為是 None。
正如我們認為的一樣,當我們使用長選項,輸出結果仍然是一樣的。
然而,我們的幫助信息對這一個新功能解釋得不是很好,但這一點仍舊是可以通過修改腳本代碼來修復的(通過 help 關鍵字)。
最后一個輸出暴露了我們程序的一個 bug。
讓我們來修復它:
import argparse parser = argparse.ArgumentParser() parser.add_argument("square", type=int, help="display a square of a given number") parser.add_argument("-v", "--verbosity", action="count", help="increase output verbosity") args = parser.parse_args() answer = args.square**2 # bugfix: replace == with >= if args.verbosity >= 2: print("the square of {} equals {}".format(args.square, answer)) elif args.verbosity >= 1: print("{}^2 == {}".format(args.square, answer)) else: print(answer)
輸出如果如下:
$ python3 prog.py 4 -vvv the square of 4 equals 16 $ python3 prog.py 4 -vvvv the square of 4 equals 16 $ python3 prog.py 4 Traceback (most recent call last): File "prog.py", line 11, in <module> if args.verbosity >= 2: TypeError: '>=' not supported between instances of 'NoneType' and 'int'
開始的輸出結果很理想,并且修復了之前的bug。也就是說,我們希望任何 >=2的值都盡可能詳細。
第三個輸出結果不是很理想
讓我們修復這個 bug:
import argparse parser = argparse.ArgumentParser() parser.add_argument("square", type=int, help="display a square of a given number") parser.add_argument("-v", "--verbosity", action="count", default=0, help="increase output verbosity") args = parser.parse_args() answer = args.square**2 if args.verbosity >= 2: print("the square of {} equals {}".format(args.square, answer)) elif args.verbosity >= 1: print("{}^2 == {}".format(args.square, answer)) else: print(answer)
我們剛剛引入了另外一個關鍵詞:default。我們把它設置為 0 是為了讓它可以進行整數比較。記住,默認情況下,如果一個可選參數沒有被指定,它將得到 None 值,它不能進行整數比較(因此會報 TypeError 異常)。
這時我們再執行:
$ python3 prog.py 4 16
就目前為止所學到的東西,您可以走的很遠,而且我們只是從頭開始。 argparse模塊功能非常強大,在結束本教程之前,我們將對其進行更多的探索。
深入一點
如果我們想擴展我們的小程序以執行其他冪運算,而不僅僅是做平方:
import argparse parser = argparse.ArgumentParser() parser.add_argument("x", type=int, help="the base") parser.add_argument("y", type=int, help="the exponent") parser.add_argument("-v", "--verbosity", action="count", default=0) args = parser.parse_args() answer = args.x**args.y if args.verbosity >= 2: print("{} to the power {} equals {}".format(args.x, args.y, answer)) elif args.verbosity >= 1: print("{}^{} == {}".format(args.x, args.y, answer)) else: print(answer)
輸出:
$ python3 prog.py usage: prog.py [-h] [-v] x y prog.py: error: the following arguments are required: x, y $ python3 prog.py -h usage: prog.py [-h] [-v] x y positional arguments: x the base y the exponent optional arguments: -h, --help show this help message and exit -v, --verbosity $ python3 prog.py 4 2 -v 4^2 == 16
請注意,到目前為止,我們一直在使用 verbosity 級別來更改顯示的文本。下面的示例改為使用 verbosity 級別來顯示更多文本:
import argparse parser = argparse.ArgumentParser() parser.add_argument("x", type=int, help="the base") parser.add_argument("y", type=int, help="the exponent") parser.add_argument("-v", "--verbosity", action="count", default=0) args = parser.parse_args() answer = args.x**args.y if args.verbosity >= 2: print("Running '{}'".format(__file__)) if args.verbosity >= 1: print("{}^{} == ".format(args.x, args.y), end="") print(answer)
結果:
$ python3 prog.py 4 2 16 $ python3 prog.py 4 2 -v 4^2 == 16 $ python3 prog.py 4 2 -vv Running 'prog.py' 4^2 == 16
沖突的選項
目前為止,我們一直使用 argparse.ArgumentParser 實例的兩個方法。讓我們引入第三個:add_mutually_exclusive_group()。它允許我們指定相互沖突的選項。讓我們修改程序的其他部分,以便讓我們引入新功能變得更有意義:我們將引入 --quiet 選項,它是 --verbose 的對立:
import argparse parser = argparse.ArgumentParser() group = parser.add_mutually_exclusive_group() group.add_argument("-v", "--verbose", action="store_true") group.add_argument("-q", "--quiet", action="store_true") parser.add_argument("x", type=int, help="the base") parser.add_argument("y", type=int, help="the exponent") args = parser.parse_args() answer = args.x**args.y if args.quiet: print(answer) elif args.verbose: print("{} to the power {} equals {}".format(args.x, args.y, answer)) else: print("{}^{} == {}".format(args.x, args.y, answer))
我們的程序更加簡單了,為了演示我們丟掉了一些功能。總之,下面是輸出結果:
$ python3 prog.py 4 2 4^2 == 16 $ python3 prog.py 4 2 -q 16 $ python3 prog.py 4 2 -v 4 to the power 2 equals 16 $ python3 prog.py 4 2 -vq usage: prog.py [-h] [-v | -q] x y prog.py: error: argument -q/--quiet: not allowed with argument -v/--verbose $ python3 prog.py 4 2 -v --quiet usage: prog.py [-h] [-v | -q] x y prog.py: error: argument -q/--quiet: not allowed with argument -v/--verbose
那應該很容易理解。在最后一個輸出里,我添加了長選項與短選項的混合,這樣你能看到選項順序的靈活性。
在我們總結之前,你可能會想告訴用戶你程序主要用來做什么,以防他們不知道:
import argparse parser = argparse.ArgumentParser(description="calculate X to the power of Y") group = parser.add_mutually_exclusive_group() group.add_argument("-v", "--verbose", action="store_true") group.add_argument("-q", "--quiet", action="store_true") parser.add_argument("x", type=int, help="the base") parser.add_argument("y", type=int, help="the exponent") args = parser.parse_args() answer = args.x**args.y if args.quiet: print(answer) elif args.verbose: print("{} to the power {} equals {}".format(args.x, args.y, answer)) else: print("{}^{} == {}".format(args.x, args.y, answer))
需要注意的是幫助信息有些許的變化。注意 [-v | -q] 是告訴我們可以使用任意一個,但不能同時使用:
$ python3 prog.py --help usage: prog.py [-h] [-v | -q] x y calculate X to the power of Y positional arguments: x the base y the exponent optional arguments: -h, --help show this help message and exit -v, --verbose -q, --quiet
總結
argparse模塊提供的功能遠遠超出此處所示。它的文檔非常詳細和透徹,并有許多示例。相信你在閱讀完本次的 Python學習教程后,應該輕松消化它們,而不會感到不知所措。更多的 Python學習教程也會繼續為大家更新,伙伴們有不清楚的地方,可以留言!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。