|簡體中文

比思論壇

 找回密碼
 按這成為會員
搜索



查看: 1235|回復: 0
打印 上一主題 下一主題

用 Python 解析命令行参数

[複製鏈接]

56

主題

0

好友

490

積分

中學生

Rank: 3Rank: 3

  • TA的每日心情

    6 天前
  • 簽到天數: 204 天

    [LV.7]常住居民III

    推廣值
    0
    貢獻值
    0
    金錢
    156
    威望
    490
    主題
    56
    樓主
    發表於 2020-12-30 09:06:08
    本文的目标很简单:帮助新的 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 <stdio.h>
    • /* 一个打印 argv 内容的简单 C 程序。 */
    • int main(int argc, char **argv) {
    •     int i;
    •    
    •     for(i=0; i<argc; i++)
    •       printf("%s\n", argv[i]);
    • }
    早期对命令行标准化的尝试
    命令行武器库中的下一个武器是一个叫做 getoptC 标准库函数。这个函数允许程序员解析开关,即前面带破折号的参数(比如 -x),并且可以选择将后续参数与它们的开关配对。想想 /bin/ls -alSh 这样的命令调用,getopt 就是最初用来解析该参数串的函数。使用 getopt 使命令行的解析变得相当简单,并改善了用户体验(UX)。
    • include <stdio.h>
    • #include <getopt.h>
    • #define OPTSTR "b:f:"
    • extern char *optarg;
    • int main(int argc, char **argv) {
    •     int opt;
    •     char *bar = NULL;
    •     char *foo = NULL;
    •    
    •     while((opt=getopt(argc, argv, OPTSTR)) != EOF)
    •        switch(opt) {
    •           case 'b':
    •               bar = optarg;
    •               break;
    •           case 'f':
    •               foo = optarg;
    •               break;
    •           case 'h':
    •           default':
    •               fprintf(stderr, "Huh? try again.");
    •               exit(-1);
    •               /* NOTREACHED */
    •        }
    •     printf("%s\n", foo ? foo : "Empty foo");
    •     printf("%s\n", bar ? bar : "Empty bar");
    • }
    就个人而言,我希望 Python 有开关,但这永远、永远不会发生
    GNU 时代
    GNU 项目出现了,并为他们实现的传统 Unix 命令行工具引入了更长的格式参数,比如--file-format foo。当然,我们这些 Unix 程序员很讨厌这样,因为打字太麻烦了,但是就像我们这些旧时代的恐龙一样,我们输了,因为用户喜欢更长的选项。我从来没有写过任何使用 GNU 风格选项解析的代码,所以这里没有代码示例。
    GNU 风格的参数也接受像 -f foo 这样的短名,也必须支持。所有这些选择都给程序员带来了更多的工作量,因为他们只想知道用户要求的是什么,然后继续进行下去。但用户得到了更一致的用户体验:长格式选项、短格式选项和自动生成的帮助,使用户不必再试图阅读臭名昭著的难以解析的手册页面(参见 ps 这个特别糟糕的例子)。
    但我们正在讨论 Python
    重要聲明:本論壇是以即時上載留言的方式運作,比思論壇對所有留言的真實性、完整性及立場等,不負任何法律責任。而一切留言之言論只代表留言者個人意見,並非本網站之立場,讀者及用戶不應信賴內容,並應自行判斷內容之真實性。於有關情形下,讀者及用戶應尋求專業意見(如涉及醫療、法律或投資等問題)。 由於本論壇受到「即時上載留言」運作方式所規限,故不能完全監察所有留言,若讀者及用戶發現有留言出現問題,請聯絡我們比思論壇有權刪除任何留言及拒絕任何人士上載留言 (刪除前或不會作事先警告及通知 ),同時亦有不刪除留言的權利,如有任何爭議,管理員擁有最終的詮釋權。用戶切勿撰寫粗言穢語、誹謗、渲染色情暴力或人身攻擊的言論,敬請自律。本網站保留一切法律權利。

    手機版| 廣告聯繫

    GMT+8, 2024-11-1 06:50 , Processed in 0.015955 second(s), 20 queries , Gzip On, Memcache On.

    Powered by Discuz! X2.5

    © 2001-2012 Comsenz Inc.

    回頂部