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

其他关于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

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


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 与 argparse 详解))