如何优雅地解析命令行选项(上)

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: 随着我们编程经验的增长,对命令行的熟悉程度日渐加深,想来很多人会渐渐地体会到使用命令行带来的高效率。自然而然地,我们自己写的很多程序(或者干脆就是脚本),也希望能够像原生命令和其他程序一样,通过运行时输入的参数就可以设定、改变程序的行为;而不必一层层找到相应的配置文件,然后还要定位到相应内容、修改、保存、退出……

如何优雅地解析命令行选项

随着我们编程经验的增长,对命令行的熟悉程度日渐加深,想来很多人会渐渐地体会到使用命令行带来的高效率。

自然而然地,我们自己写的很多程序(或者干脆就是脚本),也希望能够像原生命令和其他程序一样,通过运行时输入的参数就可以设定、改变程序的行为;而不必一层层找到相应的配置文件,然后还要定位到相应内容、修改、保存、退出……

想想就很麻烦好吗

01

1. 手动解析

所以让我们开始解析命令行参数吧~

在以前关于模块的文章中我们提到过sys.args这个变量,其中保存的就是调用当前脚本时传入的命令行参数。

我们先观察一下这个变量:

# test_sys.py
import sys
print(sys.argv)

通过命令行调用:

$ python test_sys.py -d today -t now --author justdopython --country China --auto

得到如下输出结果:

['test_sys.py', '-d', 'today', '-t', 'now', '--author', 'justdopython', '--country', 'China', '--auto']

可见,sys.argv其实就是将命令行参数按空格切分,得到的一个字符串列表。此外,命令行参数的第一个就是当前运行的脚本名称。

我们如果想要提取出各个参数及其对应的值,首先得区分出命令行的长参数和短参数,它们分别由“--”和“-”开头作为标识。所以我们也以此作为判断长短参数的条件:

import sys
for command_arg in sys.argv[1:]:
    if command_arg.startswith('--'):
        print("%s 为长参数" % command_arg)
    elif command_arg.startswith('-'):
        print("%s 为短参数" % command_arg)

测试结果:

$ python manually_parse_argv.py -d today -t now --author justdopython --country China --auto
-d 为短参数
-t 为短参数
--author 为长参数
--country 为长参数
--auto 为长参数

紧接着,我们需要在解析出长短参数这一步的基础上,再解析出对应的参数值:

# manually_parse_argv.py
import sys
# 由于sys.argv的第一个变量是当前脚本名称,因此略过
for index, command_arg in enumerate(sys.argv[1:]):
    if command_arg.startswith('--'):
        try:
            value = sys.argv[1:][index+1]
            if not value.startswith('-'):
                print("%s 为长参数,参数值为 %s" % (command_arg, value))
                continue
        except IndexError:
            pass
        print("%s 为长参数,无参数值" % command_arg)
    elif command_arg.startswith('-'):
        try:
            value = sys.argv[1:][index+1]
            if not value.startswith('-'):
                print("%s 为短参数,参数值为 %s" % (command_arg, value))
                continue
        except IndexError:
            pass
        print("%s 为短参数,无参数值" % command_arg)

再测试一下:

$ python manually_parse_argv.py -d today -t now --author justdopython --country China --auto
-d 为短参数,参数值为 today
-t 为短参数,参数值为 now
--author 为长参数,参数值为 justdopython
--country 为长参数,参数值为 China
--auto 为长参数,无参数值

看起来还不错。

但是再看看我们的代码……真正的逻辑还没开始,反倒是为了解析命令行参数已经写了几十行代码。这一点都不pythonic——这还不包括一些其他关于异常情况的处理。

更何况是要在每个类似的程序中加入这么一段程序了。

2. getopt模块帮您忙

Python的好处就在于,生态过于丰富,几乎你要用到的每个功能,都已经有人为你写好了现成的模块以供调用。

衣来伸手饭来张口的日子除了能在梦中想想,在用Python写程序的时候也不是不可以奢望。

比如命令行参数解析,就有一个名为getopt的模块,既能够准确区分长短命令行参数,也能够恰当地提取命令行参数的值。

咱们先来看看:

# test_getopt.py
import sys
import getopt
opts, args = getopt.getopt(sys.argv[1:], 'd:t:', ["author=", "country=", "auto"])
print(opts)
print(args)

打印结果:

$ python test_getopt.py -d today -t now --author justdopython --country China --auto
[('-d', 'today'), ('-t', 'now'), ('--author', 'justdopython'), ('--country', 'China'), ('--auto', '')]
[]

下面我们来分别解释一下相关参数的含义。

getopt模块中的getopt函数用于解析命令行参数。

该函数接受三个参数:args,shortopts和longopts,分别代表“命令行参数”,“要接收的短选项”和“要接收的长选项”。

其中args和longopts均为字符串组成的列表,而shortopts则为一个字符串。

同样地,由于sys.argv的第一个值为当前脚本名称,所以多数情况下我们会选择向args参数传入sys.argv[1:]的值。

而shortopts这个参数接受的字符串则表示需要解析哪些短选项,字符串中每个字母均表示一个短选项:

import sys
import getopt
opts, args = getopt.getopt(sys.argv[1:], 'dt')
print(opts)
print(args)
目录
相关文章
|
3月前
|
域名解析 网络协议 安全
在Linux中,想在命令行下访问某个网站,并且该网站域名还没有解析,如何做?
在Linux中,想在命令行下访问某个网站,并且该网站域名还没有解析,如何做?
|
2月前
|
Python
命令行解析工具 argparse
命令行解析工具 argparse
48 14
|
3月前
|
存储 Go UED
精通Go语言的命令行参数解析
【8月更文挑战第31天】
40 0
|
3月前
|
存储 Java 测试技术
解析 -XX:+UseCompressedOops JVM 选项
【8月更文挑战第21天】
50 0
|
3月前
|
SQL 分布式计算 算法
【python】python指南(二):命令行参数解析器ArgumentParser
【python】python指南(二):命令行参数解析器ArgumentParser
44 0
|
3月前
|
Go
【go笔记】使用标准库flag解析命令行参数
【go笔记】使用标准库flag解析命令行参数
|
3月前
|
Python
python命令行解析模块argparse
python命令行解析模块argparse
|
4月前
|
存储 Python 容器
`click`是一个用于构建命令行接口的Python包,它提供了简单、可组合的命令行解析器。
`click`是一个用于构建命令行接口的Python包,它提供了简单、可组合的命令行解析器。
|
6月前
|
存储 开发者 Python
Python中的argparse模块:命令行参数解析的利器
Python中的argparse模块:命令行参数解析的利器
60 2
|
6月前
|
存储 Linux Android开发
Rockchip u-boot阶段命令行和代码方式读取u盘内容并解析
Rockchip u-boot阶段命令行和代码方式读取u盘内容并解析
742 2

推荐镜像

更多