美文网首页Python
在Python中处理命令行参数详解(sys.argv 与 arg

在Python中处理命令行参数详解(sys.argv 与 arg

作者: 超级超级小天才 | 来源:发表于2020-12-03 21:49 被阅读0次

    其他关于Python的总结文章请访问:https://www.jianshu.com/nb/47435944

    在Python中处理命令行参数详解(sys.argv 与 argparse 详解)

    在运行python程序的时候,往往需要传入一些参数,本节主要介绍两种设置传入命令行参数的方法。

    sys.argv

    使用sys.argv处理传入参数,需要引入sys模块:

    import sys
    

    sys.argv即是使用命令行运行 python 命令(或者 python3 命令)时获取到的命令行参数数组,它是一个list,包含了python(或者python3)命令后边传入的内容,包括紧跟在 python/python3 后边的第一个脚本的名称,后边其他的参数,如果有的话,则是按照空格来标识不同的参数,即使用空格隔开的元素(不论是整数、字符串、小数等)都视为一个独立的参数,比如如下的程序:

    import sys
    
    print(type(sys.argv))
    print(len(sys.argv))
    print(sys.argv)
    

    我们在命令行中使用如下命令运行该脚本:

    python main.py 123 1.5 hello world
    

    就会得到如下的运行结果:

    <class 'list'>
    5
    ['main.py', '123', '1.5', 'hello', 'world']
    

    从结果可以看到,这些参数在sys.argv中都以字符串的形式存储,所以如果想得到整数、小数等,需要使用 int、float 等进行显式转换:

    import sys
    
    a = int(sys.argv[1])
    b = int(sys.argv[2])
    
    print(a+b)
    

    调用:

    main.py 123 456
    

    就会得到579的结果。

    需要注意的是,脚本名称本身占据了sys.argv[0],所以其他传入的参数实际是从sys.argv[1]开始的。

    这种方式虽然简单,但是可用性比较小,必须按照顺序传入参数,而且我们熟悉的 --- 形式的参数是不起作用的:

    python main.py --a 123 --b 456
    ['main.py', '--a', '123', '--b', '456']
    

    所以可以使用下边的功能更加强大、复杂的第二种方法

    argparse

    argparse的使用需要引入argparse包:

    import argparse
    

    我们将这种方法称为参数解析器方式,其使用可以分为三个基本步骤:

    实例化参数解析器

    使用ArgumentParser实例化一个参数解析器:

    parser = argparse.ArgumentParser()
    

    其完整的类的签名如下(可以参考https://docs.python.org/3/library/argparse.html#argumentparser-objects):

    class argparse.ArgumentParser(prog=None, usage=None, description=None, epilog=None, parents=[], formatter_class=argparse.HelpFormatter, prefix_chars='-', fromfile_prefix_chars=None, argument_default=None, conflict_handler='error', add_help=True, allow_abbrev=True, exit_on_error=True)
    

    这里列举几个比较重要、常用的参数:

    • description:一个整体的描述,会显示在帮助文档的前边
    • epilog:结语,会显示在帮助文档的后边
    • argument_default:全局设置参数的默认值,默认为 None
    • add_help:为解析器添加一个 -h/--help 选项来显示帮助文档,默认值为 True

    添加参数设置

    实例化好一个参数解析器后就开始为其添加参数设置,使用add_argument方法:正如下边的这行代码,添加了一个 -v 或者 --version 来传入的参数,它的默认值是 1.0,数据类型是字符串,并且有帮助信息,帮助信息可以在帮助文档中显示。

    parser.add_argument('-v', '--version', default='1.0', type=str, help='print the version of the script')
    

    完整的函数签名如下(可以参考https://docs.python.org/3/library/argparse.html#the-add-argument-method):

    ArgumentParser.add_argument(name or flags...[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest])
    

    其中一些重要且常用的参数列在此处:

    • names or flags:简单说就是这个参数的名字,是必须有的参数,排在第一位(如果有多个名字就排在前几位),通常会使用“短格式”或/和“长格式”,短格式也就是使用 - 后边加上一个字母的形式,长格式则是 -- 后边跟上一个单词的形式,如我们熟知的 -v--version。参数在被解析时使用的名字是指 --- 后边的内容,比如这里的 vversion
    • type:命令行参数应当被转换成的类型,比如boolintfloatstr等。
    • default:当参数未在命令行中出现时,使用这个默认值。比如:
      parser.add_argument("--foo", default='1')
      
      在命令行调用时如果没有传入 -foo 参数,那这个参数的值就会被设置为1
    • help:对于此项参数的帮助描述,会被打印到帮助文档中。
    • action:指定该参数的动作,即如何对这个参做哪些处理,可供选择的动作有很多,这里列举一些(完整的以及对于新版的内容可以查看https://docs.python.org/3.9/library/argparse.html#action 以及 Action 类的签名:https://docs.python.org/3.9/library/argparse.html#argparse.Action
      • store:存储参数的值,也是默认的动作,即将从命令行获取的参数存储到对应名称的变量下
      • store_const:存储一个const属性的值,使用这个action时通过 const 参数指定参数值。(后边会讲到const
        parser.add_argument('--foo', action='store_const', const=42)
        
      • store_true 和 store_false:是 store_const 的特例,不需要使用const指定参数值,即默认值分别为 True 和 False
        parser.add_argument('--foo', action='store_true')
        parser.add_argument('--bar', action='store_false')
      • append:存储一个list,对于多次使用一个参数的时候很有用,会将每次使用这个参数获取的值追加的列表中,比如:
        parser.add_argument('--foo', action='append')
        
        此时如果是这样调用命令:
        python main.py --foo 1 --foo 5.2
        
        在解析时,名称 foo 对应接收到的值就是一个列表:['1', '5.2']
      • append_const:和store_const同理,存储成const属性的列表,当然也需要const参数来指定参数值:
        parser.add_argument('--str', dest='types', action='append_const', const='hello')
        parser.add_argument('--int', dest='types', action='append_const', const=20)
        
      • count: 计算一个关键字参数出现的数目或次数,例如这样设置一个参数:
        parser.add_argument('--foo','-f', action='count')
        
        然后在命令行这样调用该脚本:
        python main.py --foo --foo --foo
        
        在解析时,名称 foo (或者f)对应的值就是3
        特别说明,对于短格式的名称,可以不使用多个-隔开,这样也会被计数:
        python main.py --foo -ffff
        
        在解析时,名称 foo(或者f)对应的值就是5
      • help:如果一个参数被绑定了这个动作,他的作用就是打印帮助文档,这跟ArgumentParser中默认的add_help是完全相同的
      • version:绑定这个动作后要使用另一个参数 version 来指定打印的版本,通常是绑定给 --version 或者 -v
      • extend:会将个这个参数后边跟的一个或者多个参数值存储到列表中,他和append是很相似的但是也有不同,使用extend,对于一个参数可以跟多个参数值,但是使用append需要多次调用一个参数,每次跟上一个值,比如这样定义一个参数:
        parser.add_argument("--foo", action="extend")
        
        然后这样调用该脚本:
        python main.py --foo f1 f2 f3 f4
        
        在解析时就会将foo参数解析成一个list:['f1', 'f2', 'f3', 'f4']
    • nargs - 命令行参数应当消耗的数目,即指定这个参数后边跟的多少个参数值被吸纳到这个参数以及他的action中,可以取的值有:
      • 一个整数:指定个数,比如:
        parser.add_argument('--foo', nargs=2)
        
        表示 -foo 后边跟的两个参数值都是它的
      • '?':表示如果有一个就要一个参数,如果没有就使用default指定的值。
      • '*':所有能获取的参数,不限个数,包括零个
      • '+':和 '*' 类似,都是不限个数的参数,但是至少要有一个参数,否则会报错
        上述的三个定义可以结合正则表达式来理解,是同样的道理
    • const:对于 store_constappend_const 两个动作,这个参数是必须要给出的,它指定了调用这两个动作的时候会将const所指定的值添加到对象中
    • choices:这个参数接受一个列表做值,指定所定义的参数能够接受的命令行参数值的范围,比如:
      parser.add_argument("--foo", choices=[1, 2, 3], type=int)
      
      这表示-foo这个参数只能接受1、2、3三个值,如果传入其他值会报错,比如:
      python main.py --foo 4
      
      就会出现错误:
      usage: main.py [-h] [--foo {1,2,3}]
      main.py: error: argument --foo: invalid choice: 4 (choose from 1, 2, 3)
      
      值得一提的是,如果在使用choices参数后没有使用default设置默认值,就会默认使用choices列表中的第一个值default
    • required:默认值为 False,如果设置为True,则表示这个参数必须传入,否则会报错。

    解析获取的参数

    使用ArgumentParser.parse_args方法解析获取的参数,返回解析的结果:

    args = parser.parse_args()
    

    然后就可以使用设置中对每个参数指定的名字来获取它们的值,比如使用args.foo获取 --foo 参数获得的值

    一个完整的简单的例子

    这里有一个简单的例子,同时给出了不同的命令行参数对应的结果

    import argparse
    
    parser = argparse.ArgumentParser(description='An argparse example')
    
    parser.add_argument("--method", '-m', choices=['add', 'multiple'], help='choose whether to add or to multiply')
    parser.add_argument("--A", '-a', default=1, type=int, help="The first number")
    parser.add_argument("--B", '-b', default=2, type=int, help="The second number")
    
    args = parser.parse_args()
    
    if args.method == 'add':
        print(args.A + args.B)
    else:
        print(args.A * args.B)
    

    如下是一些调用的例子:

    >python main.py
    2
    
    >python main.py --help
    usage: main.py [-h] [--method {add,multiple}] [--A A] [--B B]
    
    An argparse example
    
    optional arguments:
      -h, --help            show this help message and exit
      --method {add,multiple}, -m {add,multiple}
                            choose whether to add or to multiply
      --A A, -a A           The first number
      --B B, -b B           The second number
    
    >python main.py --method multiple -a 10 -b 20
    200
    
    >python main.py --m add -a 10
    12
    

    相关文章

      网友评论

        本文标题:在Python中处理命令行参数详解(sys.argv 与 arg

        本文链接:https://www.haomeiwen.com/subject/szmvwktx.html