Python argparse
轉自:https://blog.ixxoo.me/argparse.html
原文:Argparse Tutorial
譯者:likebeta
本教程是對于Python標準庫中推薦使用的命令行解析模塊argparse的簡單介紹。
PS:還有其他兩個模塊實現這一功能,getopt(等同于C語言中的getopt())和棄用的optparse。因為argparse是基于optparse,所以用法很類似。
概念
讓我們先用ls來展示這篇教程將要介紹的相關特性:
$ 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. ...從上面的四個命令,我們可以了解一些概念:
- ls命令在沒有參數的情況下也是可以使用的。默認顯示當前目錄的內容。
- 如果想讓它展示不同,需要給它更多的參數。這個例子中,我們想讓它顯示目錄pypy,需要指定必要的參數。因為程序需要基于這些參數確定做些什么。這個概念類似cp, 比如最常見的cp SRC DST。第一個參數表示你要復制什么,第二個參數表示復制到哪里去。
- 現在,我想要改變程序的行為。在示例中,我們讓它顯示更多的信息,不僅僅是文件名,這里的-l就是一個可選參數。
- 最后是一個幫助文檔的片段。這些幫助對于沒有使用過這個程序的人很有幫助,他們可以通過簡單的閱讀,就可以了解程序的用法。
基礎
讓我們從一個簡單的例子開始,它(幾乎)什么都不做:
import argparse parser = argparse.ArgumentParser() parser.parse_args()運行:
$ python prog.py $ python prog.py --help usage: prog.py [-h]optional arguments:-h, --help show this help message and exit $ python prog.py --verbose usage: prog.py [-h] prog.py: error: unrecognized arguments: --verbose $ python prog.py foo usage: prog.py [-h] prog.py: error: unrecognized arguments: foo結果分析:
- 不加任何參數運行,什么也不顯示,沒有什么用。
- 第二條展示了argparse模塊的好處,幾乎什么都不做,卻得到了一個很有用的幫助信息。
- --help參數可簡寫成-h,是唯一預設的(不需要指定)。
定位參數
例子:
import argparse parser = argparse.ArgumentParser() parser.add_argument("echo") args = parser.parse_args() print args.echo運行:
$ python prog.py usage: prog.py [-h] echo prog.py: error: the following arguments are required: echo $ python prog.py --help usage: prog.py [-h] echopositional arguments:echooptional arguments:-h, --help show this help message and exit $ python prog.py foo foo結果分析:
- 我們用到了方法add_argument(),用來指定程序需要接受的命令參數,本例中的echo。
- 現在運行程序必須指定一個參數。
- 方法parse_args()通過分析指定的參數返回一些數據,如本例中的echo。
- 像魔法一樣,argparse自動生成這些變量,你可能已經注意到變量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運行:
$ python prog.py -h usage: prog.py [-h] echopositional arguments:echo echo the string you use hereoptional 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運行如下:
$ python 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運行:
$ python prog.py 4 16 $ python 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"輸出:
$ python prog.py --verbosity 1 verbosity turned on $ python prog.py $ python prog.py --help usage: prog.py [-h] [--verbosity VERBOSITY]optional arguments:-h, --help show this help message and exit--verbosity VERBOSITYincrease output verbosity $ python prog.py --verbosity usage: prog.py [-h] [--verbosity VERBOSITY] prog.py: error: argument --verbosity: expected one argument結果分析:
- 當指定--verbosity時程序就顯示一些東西,沒指定的時候就不顯示。
- 這個參數事實上是可選的,不指定它也不會出錯。如果不指定可選的參數,對應的變量就被設置為None,比如本例中的args.verbosity, 這就是為什么示例中的 if 沒有執行的原因。
- 幫助信息發生了點變化
- 當我們使用可選參數--verbosity時,也必須指定一些值。
上面的示例中可選參數--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"運行:
$ python prog.py --verbose verbosity turned on $ python prog.py --verbose 1 usage: prog.py [-h] [--verbose] prog.py: error: unrecognized arguments: 1 $ python prog.py --help usage: prog.py [-h] [--verbose]optional arguments:-h, --help show this help message and exit--verbose increase output verbosity結果分析:
- 現在多加一個標志來替代必須給出一些值,并修改了名稱來表達我們的意思。注意現在指定了一個新的關鍵詞action,并且賦值為store_ture。如果指定了這個可選參數,args.verbose就賦值為True,否則就為False。
- 多指定了值,它就會發出錯誤提示。
- 注意幫助文檔有什么不同
簡寫
如果你很熟悉命令行,你可能已經注意到我在上面已經提到了參數的簡寫,非常的簡單:
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"運行如下:
$ python prog.py -v verbosity turned on $ python 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運行:
$ python prog.py usage: prog.py [-h] [-v] square prog.py: error: the following arguments are required: square $ python prog.py 4 16 $ python prog.py 4 --verbose the square of 4 equals 16 $ python prog.py --verbose 4 the square of 4 equals 16- 為了讓程序復雜點,我們重新加上了定位參數。
- 注意到參數的順序是沒有影響的。
來看看為程序加上處理重復參數的能力會怎么樣:
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運行:
$ python prog.py 4 16 $ python prog.py 4 -v usage: prog.py [-h] [-v VERBOSITY] square prog.py: error: argument -v/--verbosity: expected one argument $ python prog.py 4 -v 1 4^2 == 16 $ python prog.py 4 -v 2 the square of 4 equals 16 $ python 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運行:
$ python 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) $ python prog.py 4 -h usage: prog.py [-h] [-v {0,1,2}] squarepositional arguments:square display a square of a given numberoptional arguments:-h, --help show this help message and exit-v {0,1,2}, --verbosity {0,1,2}increase output verbosity注意幫助信息和錯誤信息都發生了變化。
現在讓我們用一種更常用的方法來處理,類似CPython處理自己的參數(參考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我們引入了另一個關鍵詞count來統計可選參數出現的次數:
$ python prog.py 4 16 $ python prog.py 4 -v 4^2 == 16 $ python prog.py 4 -vv the square of 4 equals 16 $ python prog.py 4 --verbosity --verbosity the square of 4 equals 16 $ python prog.py 4 -v 1 usage: prog.py [-h] [-v] square prog.py: error: unrecognized arguments: 1 $ python prog.py 4 -h usage: prog.py [-h] [-v] squarepositional arguments:square display a square of a given numberoptional arguments:-h, --help show this help message and exit-v, --verbosity increase output verbosity $ python prog.py 4 -vvv 16- 和前面的版本相比這里多了一個關鍵詞(類似action="store_true")。
- 行為上也類似store_true。
- count關鍵詞的示范,大家可能在其他地方已經看過了。
- 就像store_ture,如果不指定-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運行如下:
$ python prog.py 4 -vvv the square of 4 equals 16 $ python prog.py 4 -vvvv the square of 4 equals 16 $ python prog.py 4 Traceback (most recent call last):File "prog.py", line 11, in <module>if args.verbosity >= 2: TypeError: unorderable types: NoneType() >= int()- 第一個輸出是正確的,修正了上個版本的問題,參數出現次數>=2時都能顯示詳細的信息。
- 第三個輸出還是有問題
再來修改下:
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,None是不能和整型比較的(觸發[TypeError][5]異常)。
運行結果:
$ python 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輸出:
$ python prog.py usage: prog.py [-h] [-v] x y prog.py: error: the following arguments are required: x, y $ python prog.py -h usage: prog.py [-h] [-v] x ypositional arguments:x the basey the exponentoptional arguments:-h, --help show this help message and exit-v, --verbosity $ python prog.py 4 2 -v 4^2 == 16截止到目前,我們都在利用詳細的級別來改變輸出,下面的示例演示了利用詳細的級別來顯示更多輸出:
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), print answer輸出:
$ python prog.py 4 2 16 $ python prog.py 4 2 -v 4^2 == 16 $ python prog.py 4 2 -vv Running 'prog.py' 4^2 == 16參數沖突
迄今為止,我們已經使用到了[argparse.ArgumentParser][6]的兩個方法,來看看他的另一個方法add_mutually_exclusive_group()。它可以讓我們指定某個參數和其他參數沖突。下面來修改下程序以對這個新方法有更多的了解:我們將加入參數--quiet,它和參數--verbose沖突,不能同時指定:
import argparseparser = 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.yif 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)程序很簡單,為了演示沖突,去掉了其他功能特性展示,運行結果:
$ python prog.py 4 2 4^2 == 16 $ python prog.py 4 2 -q 16 $ python prog.py 4 2 -v 4 to the power 2 equals 16 $ python 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 $ python 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 argparseparser = 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.yif 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]表明了可以使用-v或者-q,但是不能同時使用。
$ python prog.py --help usage: prog.py [-h] [-v | -q] x ycalculate X to the power of Ypositional arguments:x the basey the exponentoptional arguments:-h, --help show this help message and exit-v, --verbose-q, --quiet總結
argparse模塊提供了比我們展示的多得多的功能。它的文檔更加詳盡和深入,并且配了大量的示例。自己去深入閱讀下,文檔很容易理解。
原文地址:Argparse Tutorial
官方文檔:argparse
另外一篇:argparse - 命令行選項與參數解析(譯)
PS:第一次翻譯文檔,感覺到英語真的太差了~~o(>_<)o ~~
轉載于:https://www.cnblogs.com/leebxo/p/10590851.html
總結
以上是生活随笔為你收集整理的Python argparse的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 初始匿名函数
- 下一篇: PostgreSQL技术周刊第20期:P