argparse与click
前言
同样作为处理python命令行参数的库,
有以下几种
- getopt(简单)
- optparse(较为完善)
- argparse(更完善但还是不好用)
- click
- docopt
只记得argparse比optparse更完整一些,其他忘了.
如今又出现了一个click.
这里从使用讲起并对比一下.
argparse
基础使用
1 | import argparse |
必选参数与格式化
像是普通函数用的形参,即为必选参数
帮助会显示为python test.py m n
1 | parser.add_argument(dest="m", help="enter the m...", type=int) |
可选参数与默认值
看起来像别人写的那种参数,即为可选参数.
用参数的方法为python test.py -a <a> -b <b>.
或b与值之前可以没有空格
1 | parser.add_argument("-a", "--a_number", dest="a", help="enter the a...", type=int, default=2) |
TODO 接收列表的参数
nargs?
可多次使用的参数
像sed的-e参数一样可以多次使用的参数.
使用action中的append可以将该参数对应的值放在一个列表中
1 | parser.add_argument("--file", dest="files", action="append", type=argparse.FileType('rb')) |
出现即具有意义的flag
完全不需要指定值.
通常是默认不启用,使用该flag后则表示启用.
比如 --gpu
默认不使用,使用后表示使用GPU.
也有一些默认启用的flag使用这用方式,比如类似emacs的那种 --gui
.
想表达不启用的意图时,可以使用相反意义的flag比如 --no-gui
.
程序中通过action的赋值来定义默认行为,
store~true表示一旦出现就作为true保存~,
store~false相反~.
1 | parser.add_argument("--gui", dest="is_gui", action="store_true") |
可人为定值的flag
通常的使用场景是默认启用,可以人为指定不使用.
比如 --use-gpu=True
或 --use-gpu=False
.
但默认启用的情况下,
想表达否定意义时到底是使用 --use-gpu=False
还是使用 --no-gpu
,
就看个人喜好了.
1 | parser.add_argument("--use-gpu", dest="use_gpu", default=True) |
选择题
或者叫备选项.
从几个选项中选取可以采取的值.
argparse中使用choices定义可选的值.
1 | parser.add_argument("--method", choices=["linear", "square", "cubic"], default="linear") |
TODO 互斥参数和组合参数
比如画一个矩形,
如果使用两点式则必须要有两点,
使用中心的宽高的方式则必须要有中心和宽高.
同时不能混用
1 | # 互斥参数 |
子解析器
类似git后加的一堆子命令,
都可以通过建立argparse的子解析器来实现.
add~subparsers建立一个子解析器的容器~.
该容器只能有一个但容器内可以装互斥的多个子命令.
子命令的使用方法同一般命令.
加入的参数则成为该子命令特有的参数.
子解释器还可以有孙解释器.
子又有孙,孙又有子…
1 | subparsers = parser.add_subparsers() |
但为了方便调用不同的子命令,同时又不用多写if和else
可以使用以下技巧
set~defaults本来是用来声明默认值的~,
除了声明常量或变量,
还可以用来给子解释器声明一个成员函数.
则该函数即可与子解释器使用通用的方式绑定.
省去if和else,
和设计模式有点像.
1 | def status(args): |
click[以及与argparse的对比]
整体对比
-
优点
- click省去了dest参数,不用给参数取两个名字(调用时和内部处理时)
- click省去了args对象以及使用args.x调用的过程
- click使用自定义数据类型,并传入type的方式减少了choices这个参数
- click使用修饰器的方式直接指定命令与同名函数绑定,可以不需要先定义函数再声明作为args对象的参数,简化了流程
- click支持链式使用子命令(可能是由于linux的管道命令必须借助stdout吧)
- click好像对编译跨平台的可执行二进制文件有帮助
-
缺点
- 貌似不支持组合参数和一些非互补意义的组合参数
基础使用
使用 @click.command
来声明下方的函数是一个命令,并与同名命令绑定
使用 @click.option()
或 @click.argument
来添加参数
1 | import click |
必选参数与格式化
这里还使用nargs指定了参数的个数是不限制
1 |
可选参数和默认值
与argparse没有太大区别,带破折号即可
1 |
flag参数的使用
click里保留了值不可编辑的flag,
将具有同样效果(比如实现默认关闭,使用参数打开)但有不同做法的功能砍掉,
缩小实现效果的方法空间,代码易于理解,非常python风格.
因此要么是默认关闭,使用flag表示打开.
要么使用互斥又互补的两个相反意义的flag,可以用于表示默认开启.
但这也是click中仅存的互斥参数的用法了.
1 |
局限的互斥参数
使用斜线分隔时默认表示互斥关系,并且值只能是一个True,一个False
1 |
|
TODO 互斥参数
备选项
click通过封装数组到自定义的类型,将choice统一到type参数中,
比argparse的API简化了参数表
1 |
子命令
click用command概念来修饰一个绑定在特定参数下的命令,
值得一提的是,
函数名直接作为了自命令的名字,不用再重新取名.
而command可以附属于group概念,
group本身可以绑定一个函数,
又可以通过add~command来添加子命令~.
另外,click还支持使用多个子命令来形成链式的子命令使用方法
1 |
|
补充用的quick
可以给命令加一个gui方便参数的输入
-
写死要使用gui
核心就是一个quick.gui~it~()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19import quick
import click
def example_cmd(**argvs):
for k, v in argvs.items():
print(k, v, type(v))
if __name__ == "__main__":
quick.gui_it(example_cmd) -
可选使用gui
核心是
quick.gui_option
使用时使用–gui来指定使用GUI1
2
3
4
5
6
7
8
9
10
11
12
13
14
15import quick
import click
def example_cmd(**argvs):
for k, v in argvs.items():
print(k, v, type(v))
if __name__ == "__main__":
example_cmd()
docopt
参考
- argparse的使用
- argparse的详细使用(入门教程还是掘金好)
- argparse子命令详细
- argparse官网的最原汁原味(函数的解释是原始的,才能明白高级的用法是利用它的某个方面)
- 知乎上的对比
- click的入门
- 想看的
- 互斥参数的一种实现方法