本文首发于 HelloGitHub 公众号。
前言
在第一篇“初探 argparse”的文章中,我们初步掌握了使用 argparse 的四部曲,对它有了一个基本的体感。
但是它具体支持哪些类型的参数?这些参数该如何配置?本文将带你深入了解 argparse 的参数们。
1 | 本系列文章默认使用 Python 3 作为解释器进行讲解。 |
参数动作
你是否还记得?在上一篇四部曲中的第二步是定义参数,在这个步骤中,我们指定了 action 入参:
1 | parser.add_argument('--sum', dest='accumulate', action='store_const', |
那么这里面的 action,也就是 参数动作,究竟是用来做什么的呢?
想象一下,当我们在命令行输入一串参数后,对于不同类型的参数是希望做不同的处理的。
那么 参数动作 其实就是告诉解析器,我们希望对应的参数该被如何处理。比如,参数值是该被存成一个值呢,还是追加到一个列表中?是当成布尔的 True 呢,还是 False?
参数动作 被分成了如下 8 个类别:
store—— 保存参数的值,这是默认的参数动作。它通常用于给一个参数指定值,如指定名字:
1 | >>> parser.add_argument('--name') |
store_const—— 保存被const命名的固定值。当我们想通过是否给定参数来起到标志的作用,给定就取某个值,就可以使用该参数动作,如:
1 | >>> parser.add_argument('--sum', action='store_const', const=sum) |
store_true和store_false—— 是store_const的特殊情况,用来分别保存 True 和 False。如果为指定参数,则其默认值分别为 False 和 True,如:
1 | >>> parser.add_argument('--use', action='store_true') |
append—— 将参数值追加保存到一个列表中。它常常用于命令行中允许多个相同选项,如:
1 | >>> parser.add_argument('--file', action='append') |
append_const—— 将const命名的固定值追加保存到一个列表中(const的默认值为None)。它常常用于将多个参数所对应的固定值都保存在同一个列表中,相应的需要dest入参来配合,以放在同一个列表中,如:
不指定 dest 入参,则固定值保存在以参数名命名的变量中
1 | >>> parser.add_argument('--int', action='append_const', const=int) |
指定 dest 入参,则固定值保存在 dest 命名的变量中
1 | >>> parser.add_argument('--int', dest='types', action='append_const', const=int) |
count—— 计算参数出现次数,如:
1 | >>> parser.add_argument('--increase', '-i', action='count') |
help—— 打印解析器中所有选项和参数的完整帮助信息,然后退出。version—— 打印命令行版本,通过指定version入参来指定版本,调用后退出。如:
1 | >>> parser = argparse.ArgumentParser(prog='CMD') |
参数类别
如果说 参数动作 定义了解析器在接收到参数后该如何处理参数,那么 参数类别 就是告诉解析器这个参数的元信息,也就是参数是什么样的。比如,参数是字符串呢?还是布尔类型呢?参数是在几个值中可选的呢?还是可以给定值,等等。
下面,我们将逐一介绍不同类型的参数。
可选参数
可选参数 顾名思义就是参数是可以加上,或不加上。默认情况下,通过 ArgumentParser.add_argument 添加的参数就是可选参数。
我们可以通过 - 来指定短参数,也就是名称短的参数;也可以通过 -- 来指定长参数,也就是名称长的参数。当然也可以两个都指定。
可选参数通常用于:用户提供一个参数以及对应值,则使用该值;若不提供,则使用默认值。如:
1 | >>> parser.add_argument('--name', '-n') |
参数类型
参数类型 就是解析器参数值是要作为什么类型去解析,默认情况下是 str 类型。我们可以通过 type 入参来指定参数类型。
argparse 所支持的参数类型多种多样,可以是 int、float、bool等,比如:
1 | >>> parser.add_argument('-i', type=int) |
更厉害的是,type 入参还可以是可调用(callable)对象。这就给了我们很大的想象空间,可以指定 type=open 来把参数值作为文件进行处理,也可以指定自定义函数来进行类型检查和类型转换。
作为文件进行处理:
1 | >>> parser.add_argument('--file', type=open) |
使用自定义函数进行处理,入参为参数值,需返回转换后的结果。
比如,对于参数 --num,我们希望当其值小于 1 时则返回 1,大于 10 时则返回 10:
1 | >>> def limit(string): |
参数默认值
参数默认值 用于在命令行中不传参数值的情况下的默认取值,可通过 default 来指定。如果不指定该值,则参数默认值为 None。
比如:
1 | >>> parser.add_argument('-i', default=0, type=int) |
位置参数
位置参数 就是通过位置而非是 - 或 -- 开头的参数来指定参数值。
比如,我们可以指定两个位置参数 x 和 y ,先添加的 x 位于第一个位置,后加入的 y 位于第二个位置。那么在命令行中输入 1 2的时候,分别对应到的就是 x 和 y:
1 | >>> parser.add_argument('x') |
可选值
可选值 就是限定参数值的内容,通过 choices 入参指定。
有些情况下,我们可能需要限制用户输入参数的内容,只能在预设的几个值中选一个,那么 可选值 就派上了用场。
比如,指定文件读取方式限制为 read-only 和 read-write:
1 | >>> parser.add_argument('--mode', choices=('read-only', 'read-write')) |
互斥参数
互斥参数 就是多个参数之间彼此互斥,不能同时出现。使用互斥参数首先通过 ArgumentParser.add_mutually_exclusive_group 在解析器中添加一个互斥组,然后在这个组里添加参数,那么组内的所有参数都是互斥的。
比如,我们希望通过命令行来告知乘坐的交通工具,要么是汽车,要么是公交,要么是自行车,那么就可以这么写:
1 | >>> group = parser.add_mutually_exclusive_group() |
可变参数列表
可变参数列表 用来定义一个参数可以有多个值,且能通过 nargs 来定义值的个数。
若 nargs=N,N为一个数字,则要求该参数提供 N 个值,如:
1 | >>> parser.add_argument('--foo', nargs=2) |
若 nargs=?,则要求改参数提供 0 或 1 个值,如:
1 | >>> parser.add_argument('--foo', nargs='?') |
若 nargs=*,则要求改参数提供 0 或多个值,如:
1 | >>> parser.add_argument('--foo', nargs='*') |
若 nargs=?,则要求改参数至少提供 1 个值,如:
1 | >>> parser.add_argument('--foo', nargs='+') |
小节
在了解了参数动作和参数类别后,是不是渐渐开始对使用 argparse 胸有成竹了呢?至少,用现在学到的知识来完成简单的命令行工具已经不再话下了。
在下一篇文章中,我们来继续深入了解 argparse 的功能,如何修改参数前缀,如何定义参数组,如何定义嵌套的解析器,如何编写自定义动作等,让我们拭目以待吧~
相关文章
- Python 命令行之旅:初探 argparse
- Python 命令行之旅:深入 argparse(一)
- Python 命令行之旅:深入 argparse(二)
- Python 命令行之旅:使用 argparse 实现 git 命令
- Python 命令行之旅:初探 docopt
- Python 命令行之旅:深入 docopt
- Python 命令行之旅:使用 docopt 实现 git 命令
- Python 命令行之旅:初探 click
- Python 命令行之旅:深入 click(一)
- Python 命令行之旅:深入 click(二)
- Python 命令行之旅:深入 click(三)
- Python 命令行之旅:深入 click(四)
- Python 命令行之旅:使用 click 实现 git 命令
- Python 命令行之旅:初探 fire
- Python 命令行之旅:深入 fire(一)
- Python 命令行之旅:深入 fire(二)
- Python 命令行之旅:使用 fire 实现 git 命令
- Python 命令行之旅:argparse、docopt、click 和 fire 总结篇
- Python 命令行大乱斗
