返回顶部
首页 > 资讯 > 后端开发 > Python >详解Python如何优雅地解析命令行
  • 626
分享到

详解Python如何优雅地解析命令行

2024-04-02 19:04:59 626人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

目录1. 手动解析2. getopt模块总结如何优雅地解析命令行选项 随着我们编程经验的增长,对命令行的熟悉程度日渐加深,想来很多人会渐渐地体会到使用命令行带来的高效率。 自然而然地

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

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

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

想想就很麻烦好吗

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)

输出结果:

$ python test_getopt.py -d  -t
[('-d', ''), ('-t', '')]
[]

当然,如果输入的参数少于预期,也不会导致解析失败:

$ python test_getopt.py  -t
[('-t', '')]
[]

但要是给出了预期之外的参数,就会导致模块抛错:

$ python test_getopt.py -d  -t -k
Traceback (most recent call last):
  File "test_getopt.py", line 11, in <module>
    opts, args = getopt.getopt(sys.argv[1:], 'dt')
      ...
    raise GetoptError(_('option -%s not recognized') % opt, opt)
getopt.GetoptError: option -k not recognized

这样的处理逻辑也符合我们使用命令的体验,可以简单地理解为“宁缺毋滥”。

如果短参数相应的字母后带了一个冒号:,则意味着这个参数需要指定一个参数值。getopt会将该参数对应的下一个命令行参数作为参数值(而不论下一个参数是什么形式):

import sys
import getopt


opts, args = getopt.getopt(sys.argv[1:], 'd:t')

print(opts)
print(args)

# $ python test_getopt.py -d  -t
# [('-d', '-t')]
# []

此外,一旦getopt在预期接收到长短选项的位置没有找到以“--”或“-”开头的字符串,就会终止解析过程,剩下的未解析字符串均放在返回元组的第二项中返回。

$ python test_getopt.py -d d_value o --pattern -t
[('-d', 'd_value')]
['o', '--pattern', '-t']

类似地,longopts参数表示需要解析的长参数。

列表中的每一个字符串代表一个长参数:

import sys
import getopt


opts, args = getopt.getopt(sys.argv[1:], '', ["author", "country"])

print(opts)
print(args)

# $ python test_getopt.py --author  --country
# [('--author', ''), ('--country', '')]
# []

要解析带有参数值的长参数,还应在每个长参数后附带一个等于号(=),以标识该参数需要带值:

import sys
import getopt


opts, args = getopt.getopt(sys.argv[1:], '', ["author=", "country"])

print(opts)
print(args)

# $ python test_getopt.py --author justdopython --country
# [('--author', 'justdopython'), ('--country', '')]
# []

所以最终就得到了我们一开始的解析结果:

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', '')]
# []

解析完成后,我们再从opts中提取相应的值即可。

懒人福音

getopt除了替我们节省了编写命令行参数解析代码的时间和精力,另一方面还可以让你在输入命令行参数时少打几个字母——当然,严谨来讲,我们并不建议此类行为。慎用,慎用!

getopt对长参数的解析支持前缀匹配,只要输入的参数能够与某个指定参数唯一匹配,同样能够完成预期解析。

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

可以看到,author和country两个参数我们都只输入了一部分,但是getopt依然进行了正确的解析。

总结

本文讲解了使用Python解析命令行参数的两种方式,一种是略显笨重的手动解析,即自己编写程序自定义解析;另一种则是调用现成、且更加健壮的getopt模块来完成解析。

从此以后,我们终于可以摆脱繁琐的配置文件,用一种优雅简洁的方式来修改程序的行为了。

以上就是详解Python如何优雅地解析命令行的详细内容,更多关于Python解析命令行的资料请关注编程网其它相关文章!

--结束END--

本文标题: 详解Python如何优雅地解析命令行

本文链接: https://lsjlt.com/news/118742.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 详解Python如何优雅地解析命令行
    目录1. 手动解析2. getopt模块总结如何优雅地解析命令行选项 随着我们编程经验的增长,对命令行的熟悉程度日渐加深,想来很多人会渐渐地体会到使用命令行带来的高效率。 自然而然地...
    99+
    2024-04-02
  • Python API 与 UNIX 命令行:如何优雅地结合使用?
    Python是一种高级编程语言,可用于开发各种类型的应用程序。而UNIX命令行是一种基于文本的用户界面,用于操作UNIX系统。Python API和UNIX命令行都是非常强大的工具,如果能够将它们结合使用,将会是一种非常优雅的方式来处理各...
    99+
    2023-06-26
    api unix npm
  • Python命令行解析器argparse详解
    目录第1章 argparse简介1.1 解析1.2 argparse定义三步骤1.3  代码示例第2章 参数详解2.1 创建一个命令行解析器对象:ArgumentParse...
    99+
    2024-04-02
  • 一文详解Python如何优雅地对数据进行分组
    假设我们有这样一种数据: data = [     ("apple", 30), ("apple", 35),     ("apple", 32), ("pear", 60),   ...
    99+
    2024-04-02
  • 详解Python命令行解析工具Argparse
    最近在研究pathon的命令行解析工具,argparse,它是Python标准库中推荐使用的编写命令行程序的工具。 以前老是做UI程序,今天试了下命令行程序,感觉相当好,不用再花大把时间去研究界面问题,尤其...
    99+
    2022-06-04
    命令行 详解 工具
  • 详解C#如何优雅地终止线程
    目录需求说明初始版本进阶版本最终版本在刚接触后台线程的时候,觉得线程神秘且高深,并且时常有先辈们千叮万嘱:能不用的时候,尽量不要用,千万不要滥用线程,否则会发生预料不到的结果。在接触...
    99+
    2023-03-21
    C#终止线程 C#线程
  • 解析golang中如何优雅地关闭http服务
    Golang是一种非常流行的编程语言,它具有高效的并发处理能力和优秀的性能表现。相信许多golang的开发人员都会遇到一个这样的问题,在golang中如何优雅地关闭http服务?首先,我们需要知道,创建一个http服务是比较容易的,只需要几...
    99+
    2023-05-14
  • Python 命令行 prompt_toolkit 库详解
    目录一. 使用 Bash 下常用快捷键二. 实现查找历史命令三. 根据历史输入自动提示四. 实现输入的自动补全Python 的第三方库 prompt_toolkit 用于打造交互式命...
    99+
    2024-04-02
  • python命令行参数详解
    在Python中,可以通过命令行传递参数给脚本。这些参数可以在脚本内部使用,以便根据不同的输入执行不同的操作。Python命令行参数的详解:1、位置参数:在命令行中按照顺序传递给脚本的参数,它们可以在脚本内部通过位置来访问;2、命令行选项:...
    99+
    2023-12-18
    python 命令行
  • iOS如何优雅地实现序列动画详解
    前言 我们的在做动效中经常会有这样的需求,A动画执行完,执行B动画,B动画执行完执行C动画这样的序列,比如如下效果: iOS 10之前,我们可能这样实现这个动画序列,实际上可能你...
    99+
    2022-05-27
    ios 序列 动画
  • Python命令行参数解析包argparse的使用详解
    目录一、argparse简介二、简单案例三、ArgumentParser参数四、add_argument指令参数解释五、vars()一、argparse简介 argparse 是 p...
    99+
    2024-04-02
  • pandas如何优雅的列转行及行转列详解
    目录一、列转行1、背景描述2.方法描述2.1 方法12.2 方法22.3 方法32.4 方法43 思考与总结4 思维延伸4.1 例子14.2 例子2二、行转列1.准备数据2.行转列实...
    99+
    2024-04-02
  • python 命令行 解析模块 optp
      Python: 使用 optparse 处理命令行参数 python optparse命令解析模块:https://www.cnblogs.com/pping/p/3989098.html python optparse模块的简单用法...
    99+
    2023-01-31
    命令行 模块 python
  • Python 在 Windows 上如何优雅地解决 LeetCode 题目?
    LeetCode 是一个在线的编程练习平台,提供丰富的算法和数据结构题目,是程序员们提高技能的好去处。而 Python 是一种简单易学、高效强大的编程语言,被广泛应用于算法和数据科学领域。那么,在 Windows 上如何用 Python ...
    99+
    2023-10-12
    http leetcode windows
  • 如何利用Proxy更优雅地处理异常详解
    代码不会全部按照我们的预期运行,可能会有意料之外的情况,为了保证程序的健壮性,要进行异常处理。 比如一个对象的所有方法,都应该做异常处理,但是,如果每个方法都加 try catch ...
    99+
    2024-04-02
  • 一文详解如何在uniapp中优雅地使用WebView
    目录从webview页面传值到uniapp中从uniapp中动态传值到webview页面调用webview中的方法总结这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 从...
    99+
    2023-01-03
    uniapp使用webview的方法 uniapp和webview实时交互 uniapp使用webview
  • Python如何优雅地处理NaN
    背景 很多数据不可避免的会遗失掉,或者采集的时候采集对象不愿意透露,这就造成了很多NaN(Not a Number)的出现。这些NaN会造成大部分模型运行出错,所以对NaN的处理很有必要。 方法 1、简单粗暴地去掉 有如下data...
    99+
    2023-01-31
    优雅 Python NaN
  • 详解Python如何生成优雅的二维码
    目录一、使用MyQR生成二维码(1)模块安装(2)生成一个图像二维码二、使用qrcode生成二维码(1)模块安装(2)更准确的生成二维码(3)读取二维码中的数据二维码作为一种信息传递...
    99+
    2024-04-02
  • Python中的命令行参数解析工具之docopt详解
    前言 docopt 是一个开源的库,代码地址:https://github.com/docopt/docopt。它在 README 中就已经做了详细的介绍,并且还附带了很多例子可供学习,这篇文章也是翻译一下...
    99+
    2022-06-04
    命令行 详解 参数
  • Swift如何优雅的进行解包
    目录前言var num: Int?它是什么类型?解包的基本思路解包深入可选链的解包nullable和nonnull一点点Swift与OC的语言思考前言 对于Swift...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作