借鉴 C 语言的历史,学习如何用 Python 编写有用的 CLI 程序。
本文的目标很简单:帮助新的 Python 开发者了解一些关于命令行接口(CLI)的历史和术语,并探讨如何在 Python 中编写这些有用的程序。
最初……
首先,从 Unix 的角度谈谈命令行界面设计。
Unix 是一种计算机操作系统,也是 Linux 和 macOS(以及许多其他操作系统)的祖先。在图形用户界面之前,用户通过命令行提示符与计算机进行交互(想想如今的 Bash 环境)。在 Unix 下开发这些程序的主要语言是 C,它的功能非常强大。
因此,我们至少应该了解 C 程序的基础知识。
假设你没有读过上面那个链接的内容,C 程序的基本架构是一个叫做 main
的函数,它的签名是这样的。
int main(int argc, char **argv)
{
...
}
对于 Python 程序员来说,这应该不会显得太奇怪。C 函数首先有一个返回类型、一个函数名,然后是括号内的类型化参数。最后,函数的主体位于大括号之间。函数名 main
是运行时链接器(构造和运行程序的程序)如何决定从哪里开始执行你的程序。如果你写了一个 C 程序,而它没有包含一个名为 main
的函数,它将什么也做不了。伤心。
函数参数变量 argc
和 argv
共同描述了程序被调用时用户在命令行输入的字符串列表。在典型的 Unix 命名传统中,argc
的意思是“ 参数计数 argument count ”,argv
的意思是“ 参数向量 argument vector ”。向量听起来比列表更酷,而 argl
听起来就像一个要勒死的求救声。我们是 Unix 系统的程序员,我们不求救。我们让其他人哭着求救。
再进一步
$ ./myprog foo bar -x baz
如果 myprog
是用 C 语言实现的,则 argc
的值是 5,而 argv
是一个有五个条目的字符指针数组。(不要担心,如果这听起来过于技术,那换句话说,这是一个由五个字符串组成的列表。)向量中的第一个条目 argv[0]
是程序的名称。argv
的其余部分包含参数。
argv[0] == "./myprog"
argv[1] == "foo"
argv[2] == "bar"
argv[3] == "-x"
argv[4] == "baz"
/* 注:不是有效的 C 代码 */
在 C 语言中,你有很多方法来处理 argv
中的字符串。你可以手动地循环处理数组 argv
,并根据程序的需要解释每个字符串。这相对来说比较简单,但会导致程序的接口大相径庭,因为不同的程序员对什么是“好”有不同的想法。
include
/* 一个打印 argv 内容的简单 C 程序。 */
int main(int argc, char **argv) {
int i;
for(i=0; i