• Python技法:用argparse模块解析命令行选项


    1. 用argparse模块解析命令行选项

    我们在上一篇博客《Linux:可执行程序的Shell传参格式规范》中介绍了Linux系统Shell命令行下可执行程序应该遵守的传参规范(包括了各种选项及其参数)。Python命令行程序做为其中一种,其传参中也包括了位置参数(positional arguments)可选参数(optional arguments)

    (注意,可选参数的选项名称以---打头,位置参数和可选参数的先后顺序可以任意排布)

    那么在Python程序中我们如何解析在命令行中提供的各种选项呢?(选项保存在sys.argv中)我们可以使用argparse模块。我们用下面这个search.py程序做例子:

    1.1 创建parser对象

    首先我们需要创建parser对象:

    import argparse
    parser = argparse.ArgumentParser(description="search some files")
    

    1.2 添加选项声明

    然后使用parser.add_argument()方法添加想要支持的选项声明。add_argument()的调用参数承担了不同的功能:

    • dest指定了用来保存解析结果的属性名称。
    • metavar用于显示帮助信息,如果不指定则默认为大写的属性名。
    • action指定了与参数处理相关的行为(store表示存储单个值,append表示将多个值存到一个列表中)。

    我们尝试依次添加如下选项声明进行测试:

    解析位置参数

    parser.add_argument(dest="filenames", metavar="filename", nargs="*")
    

    该参数为位置参数,不需要像可选参数的选项一样用---打头。位置参数一般是必须要提供的(虽然这里你不提供也能保存为[])。nargs="*"表示将所有额外命令行参数保存在一个列表中。

    解析可选参数

    
    parser.add_argument("-p", "--pat", metavar="pattern", required=True, dest="patterns", action="append", help="text pattern to search for")
    

    -p--pat两种选项名称都可接收(前者是简写,后者是全称)。我们在上一篇博客说过,在调用Shell命令时规定对于简写的选项名用-p ××形式传参,对于全称的选项名我们有--pat ××--pat=××两种形式。不过Python脚本时你用-p=××也能解析,不过一般不建议这样搞。action="append"意为允许命令行参数重复多次,将所有参数值保存在列表中,require=True意味着参数必须要提供一次。

    parser.add_argument("-v", dest="verbose", action="store_true", help="verbose mode") 
    

    store_true意思为设定为一个布尔标记,标记的值取决于参数是否有提供。

    parser.add_argument("-o", dest="outfile", action="store", help="output file") 
    

    类似上面,这里store意思为接收一个单独的值并保存为字符串

    parser.add_argument("--speed", dest="speed", action="store", choices={"slow", "fast"}, default="slow", help="search speed") 
    

    同上,该参数也是接受一个值,但只能在特定范围中{"slow", "fast"}中选择,且默认"slow""

    1.2 解析选项

    然后我们就可以解析选项并使用传入的参数了:

    
    args = parser.parse_args()
    
    # 注意在使用参数时,是用的参数的dest名字
    print(args.filenames)
    print(args.patterns)
    print(args.verbose)
    print(args.outfile)
    print(args.speed)
    

    2. 测试

    以上的程序定义了一个命令解析器,我们可以设置-h选项查看其用法:

    (base) orion-orion@MacBook-Pro Python-Lang % python search.py -h        
    usage: search.py [-h] -p pattern [-v] [-o OUTFILE] [--speed {slow,fast}] [filename ...]
    
    search some files
    
    positional arguments:
      filename
    
    optional arguments:
      -h, --help            show this help message and exit
      -p pattern, --pat pattern
                            text pattern to search for
      -v                    verbose mode
      -o OUTFILE            output file
      --speed {slow,fast}   search speed
    

    接下来我们展示数据在程序中的显示方式。比如我们尝试不传入必需的-p/--pat选项参数:

    (base) orion-orion@MacBook-Pro Python-Lang % python search.py foo.txt bar.txt
    usage: search.py [-h] -p pattern [-v] [-o OUTFILE] [--speed {slow,fast}] [filename ...]
    search.py: error: the following arguments are required: -p/--pat
    

    如上所示,解释器会提醒我们参数没传入。我们注意到usage-p pattern并没有加方括号[],说明该参数不是可选的,必须要提供。

    接下来我们提供完整参数,大家可以仔细观察print()语句的输出:

    (base) orion-orion@MacBook-Pro Python-Lang % python search.py -v -p spam --pat=eggs foo.txt bar.txt 
    ['foo.txt', 'bar.txt']
    ['spam', 'eggs']
    True
    None
    slow
    

    可以看到如上所示,因为提供了参数-v,故args.verboseTrue。因为没提供-o ×××参数,故args.outfileNone

    (base) orion-orion@MacBook-Pro Python-Lang % python search.py -v -p spam --pat=eggs foo.txt bar.txt -o results
    ['foo.txt', 'bar.txt']
    ['spam', 'eggs']
    True
    results
    slow
    

    可以看到如上所示,设置了提供了-o results,故args.outfile打印结果为results

    (base) orion-orion@MacBook-Pro Python-Lang % python search.py -v -p spam --pat=eggs foo.txt bar.txt -o results --speed=fast
    ['foo.txt', 'bar.txt']
    ['spam', 'eggs']
    True
    results
    fast
    

    如上所示为提供了可选参数--speed的情况。

    3. 讨论

    一旦选项给出后,我们只需要简单地执行parser.parse()方法。这么做会处理sys.argv的值,并返回结果实例。如果我们手动处理sys.argv或者使用getopt模块(仿照类似的C库打造),就会重复编写许多argparse已经提供的代码,因此在新项目中应该优先选择argparse

    参考


    __EOF__

  • 本文作者: 猎户座
  • 本文链接: https://www.cnblogs.com/orion-orion/p/16293177.html
  • 关于博主: 本科CS系蒟蒻,机器学习半吊子,并行计算混子。
  • 版权声明: 欢迎您对我的文章进行转载,但请务必保留原始出处哦(*^▽^*)。
  • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。
  • 相关阅读:
    思科网络中如何配置扩展ACL协议
    Unity实现简单的对象池
    Spark - OnYARN 模式搭建,并使用 Scala、Java、Python 三种语言测试
    回溯去重问题
    【打卡】牛客网:BM54 三数之和
    过去式-ed的发音规则
    Java for循环每次都通过list.size()和 string.length()获取大小性能
    用pigeon kotlin swift写一个自己的插件
    【赛后总结】第十三届服务外包创新创业大赛总结——A14
    Hologres Query管理及超时处理
  • 原文地址:https://www.cnblogs.com/orion-orion/p/16293177.html