Python命令行程序做为其中一种,其传参中也包括了 位置参数(positional arguments) 和 可选参数(optional arguments) :
(注意,可选参数的选项名称以 --
或 -
打头,位置参数和可选参数的先后顺序可以任意排布)
那么在Python程序中我们如何解析在命令行中提供的各种选项呢?(选项保存在 sys.argv
中)我们可以使用 argparse
模块。我们用下面这个 search.py
程序做例子:
首先我们需要创建 parser
对象:
import argparse parser = argparse.ArgumentParser(description="search some files")
然后使用 parser.add_argument()
方法添加想要支持的选项声明。 add_argument()
的调用参数承担了不同的功能:
dest
指定了用来保存解析结果的属性名称。metavar
用于显示帮助信息,如果不指定则默认为大写的属性名。action
指定了与参数处理相关的行为( store
表示存储单个值, append
表示将多个值存到一个列表中)。我们尝试依次添加如下选项声明进行测试:
解析位置参数
parser.add_argument(dest="filenames", metavar="filename", nargs="*")
该参数为位置参数,不需要像可选参数的选项一样用 -
或 --
打头。位置参数一般是必须要提供的(虽然这里你不提供也能保存为 []
)。 nargs="*"
表示将所有额外命令行参数保存在一个列表中。
解析可选参数
parser.add_argument("-p", "--pat", metavar="pattern", required=True, dest="patterns", action="append", help="text pattern to search for")
-p
和 --pat
两种选项名称都可接收(前者是简写,后者是全称)。我们在上一篇博客说过,在调用Shell命令时规定对于简写的选项名用 -p ××
形式传参,对于全称的选项名我们有 --pat ××
和 --pat=××
两种形式。不过Python脚本时你用 -p=××
也能解析,不过一般不建议这样搞。 action="append"
意为允许命令行参数重复多次,将所有参数值保存在列表中, require=True
意味着参数必须要提供一次。
parser.add_argument("-v", dest="verbose", action="store_true", help="verbose mode")
store_true
意思为设定为一个布尔标记,标记的值取决于参数是否有提供。
parser.add_argument("-o", dest="outfile", action="store", help="output file")
类似上面,这里 store
意思为接收一个单独的值并保存为字符串
parser.add_argument("--speed", dest="speed", action="store", choices={"slow", "fast"}, default="slow", help="search speed")
同上,该参数也是接受一个值,但只能在特定范围中 {"slow", "fast"}
中选择,且默认 "slow""
。
然后我们就可以解析选项并使用传入的参数了:
args = parser.parse_args() # 注意在使用参数时,是用的参数的dest名字 print(args.filenames) print(args.patterns) print(args.verbose) print(args.outfile) print(args.speed)
以上的程序定义了一个命令解析器,我们可以设置 -h
选项查看其用法:
(base) orion-orion@MacBook-Pro Python-Lang % python search.py -h usage: search.py [-h] -p pattern [-v] [-o OUTFILE] [--speed {slow,fast}] [filename ...] search some files positional arguments: filename optional arguments: -h, --help show this help message and exit -p pattern, --pat pattern text pattern to search for -v verbose mode -o OUTFILE output file --speed {slow,fast} search speed
接下来我们展示数据在程序中的显示方式。比如我们尝试不传入必需的 -p/--pat
选项参数:
(base) orion-orion@MacBook-Pro Python-Lang % python search.py foo.txt bar.txt usage: search.py [-h] -p pattern [-v] [-o OUTFILE] [--speed {slow,fast}] [filename ...] search.py: error: the following arguments are required: -p/--pat
如上所示,解释器会提醒我们参数没传入。我们注意到 usage
中 -p pattern
并没有加方括号 []
,说明该参数不是可选的,必须要提供。
接下来我们提供完整参数,大家可以仔细观察 print()
语句的输出:
(base) orion-orion@MacBook-Pro Python-Lang % python search.py -v -p spam --pat=eggs foo.txt bar.txt ['foo.txt', 'bar.txt'] ['spam', 'eggs'] True None slow
可以看到如上所示,因为提供了参数 -v
,故 args.verbose
为 True
。因为没提供 -o ×××
参数,故 args.outfile
为 None
。
(base) orion-orion@MacBook-Pro Python-Lang % python search.py -v -p spam --pat=eggs foo.txt bar.txt -o results ['foo.txt', 'bar.txt'] ['spam', 'eggs'] True results slow
可以看到如上所示,设置了提供了 -o results
,故 args.outfile
打印结果为 results
。
(base) orion-orion@MacBook-Pro Python-Lang % python search.py -v -p spam --pat=eggs foo.txt bar.txt -o results --speed=fast ['foo.txt', 'bar.txt'] ['spam', 'eggs'] True results fast
如上所示为提供了可选参数 --speed
的情况。
一旦选项给出后,我们只需要简单地执行 parser.parse()
方法。这么做会处理 sys.argv
的值,并返回结果实例。如果我们手动处理 sys.argv
或者使用 getopt
模块(仿照类似的C库打造),就会重复编写许多 argparse
已经提供的代码,因此在新项目中应该优先选择 argparse
。