Python开发命令行程序

用 Python 开发命令行程序,应该如何选择?结合最近个人使用体验做一个简单的分享。

先列出最终用上的库:

  • Argparse
  • Rich
  • Click
  • Cmd2
  • Prompt Toolkit

说明:以下所谓的优缺点都是相对初学者上手而言的,不是说谁比谁差。需求变化的情况下,某些缺点反而是优点,反之亦然。

Argparse

这是 Python 标准库自带的专门用来解析命令行参数的模块。

优点是无需额外安装了,功能也比较完备。

缺点是使用起来略显麻烦,有的方法参数不是很直观。

如名所示,该模块功能比较单一,只解析参数,其它一概不管。解析完参数之后的命令调度还得用户自己实现。

Rich

这是一个看名字就非常想用的库:

非常火的一个库,主要用于终端美化输出。

又富又美,谁不想拥有呢?😂

严格来说,rich 并不是命令行库,而是终端工具。当然,命令行和终端基本上不分家,算一个赛道也正常。

这个库的优点就是输出效果颜值高,用法也简单。

然而由于它不是用来实现命令行的,所以基本不能单独用它。

Click

Click 是著名的 Flask 项目分离出来的命令行工具。

不同于上面两个库专注解决某个功能,Click 是一个命令行框架

argparse 有的参数解析功能 Click 都有了,还补全了命令调用的部分:使用装饰器来定义参数,让参数和命令不再分家。

除此之外,Click 还提供了一些辅助功能。所以,可以很快速地使用 Click 实现一个功能完备的命令行程序。

Click 也提供了简单的终端样式美化,但是效果没 Rich 那么好。所以如果想要显示效果更好,可以把两者结合来用。

没错,我不是第一个有这个想法的人,GitHub 上有一个 rich-click 库,直接拿来用就行了。

不过,Click 主要用来实现那种「敲一个命令就运行一次」的命令,如果你想要实现的是 REPL 的交互模式,就不方便了。

没错,我仍然不是第一个有此想法的人,有人实现了 click-repl 库。

此外,作为框架,设计者就是希望你在它的范围内行事,如果你的程序想跳出这个范围,只想集成其中的某个能力,这时反而会遇到麻烦。

Cmd2

Python 的标准库里有个模块叫 cmd,它提供了一个非常简单的交互式命令行框架。Python 中的交互式 Debug 工具 pdb 就是基于 cmd 实现的。

所谓交互式,就是先敲一个主命令,进入到命令循环中,然后可以执行其中的各个子命令。

标准库里的工具虽然能用,但是离实际的需求差的有点多。例如,连最起码的参数解析功能都不具备(那是 argparse 模块的活)

为了满足常用需求,Cmd2 在标准库的基础上扩展了大量功能,例如,集成了 Argparse 来做参数解析,实现按 Tab 键自动提示、自动完成等。

Cmd2 也支持基础的终端样式,可以设置文字和背景颜色,如果想要进一步美化输出,可以考虑结合 Rich 来使用。

这个库目前 GitHub 上的 Star 还不多,可能和文档写得不够详细有关,不过其中代码里的注释却很详细。

Prompt_Toolkit

最后出场的这个堪称神器了,虽然严格来说,它也不是命令行工具。

先简单解释几个概念:

所谓的命令行,全称是命令行界面,即 CLICommand Line Interface),与之经常相提并论的是 GUIGraphical User Interface),也就是图形化用户界面

其实还有一个比较小众的 TUI,即 Terminal User Interface,即终端用户界面。这里的 T 也可以解释为 Text-based,即基于文本的用户界面

一个最常见到 TUI 的地方是在安装不带桌面的操作系统的时候(例如 Ubuntu):

Prompt_Toolkit 就是一个 TUI 的框架。它可以帮助我们在终端上绘制菜单,对话框,状态栏,窗口,按钮,单选框等用户界面,还能自定义快捷键,实现弹窗,界面刷新等功能。

下面是使用 Prompt_Toolkit 实现的 ptpython,一个增强版的 Python REPL:

下面是用 Python 实现的 Pymux(类似 Tmux),可以在终端划分多个窗口,非常 Nice。

如果不想使用 GUI 编程,又想在终端实现功能强大的用户界面,Prompt_Toolkit 是不二之选。

Rich 的作者新推出的 textual 也是 TUI 框架,号称可以和开发 Web 一样开发终端应用。看过作者的展示,结合了 Rich 的高颜值,非常酷炫,但是貌似现在还不够成熟,所以没有贸然入坑。

总结

根据不同的需求,我的推荐如下:

  • 非交互的命令行:Click(不需要 Argparse,有高颜值需求的加上 Rich)
  • 交互式的命令行:Cmd2(内部使用了 Argparse,有高颜值需求的加上 Rich)
  • 定制化的终端界面:使用 Argparse 解析参数,使用 Prompt_Toolkit 设计界面

链接:

Davy
Davy
学习📚 技术👨‍💻 投资📈

一些心得体会,希望能对你有所帮助🚀。