python模块 argparse--操作命令行参数

参考文档:https://docs.python.org/zh-cn/3.8/library/argparse.html

  • argparse模块可以让你轻松编写用户友好的命令行接口
  • 程序定义它需要的参数,然后argparse知道如何从sys.argv解析出那些参数,并在用户给程序传入无效参数时报出错误信息。
  • argparse模块还会自动生成帮助和使用手册。

1、创建解析器

  • ArgumentParser对象包含将命令行解析成Python数据类型所需的全部信息。
  • 给ArgumentParser添加程序参数是通过调用add_argument()方法完成的。通常,add_argument()方法将指定ArgumentParser如何获取命令行字符串并将其转换为python对象。
  • ArgumentParser通过parse_args()方法解析参数。它将检查命令行,把每个参数转换为适当的类型然后调用相应的操作。
    参数信息在调用parse_args()时被存储和使用

import argparse

parser = argparse.ArgumentParser(description='Process some integers.')    #创建解析器
parser.add_argument('integers', metavar='N', type=int, nargs='+',         #添加一个位置参数
                    help='an integer for the accumulator')
parser.add_argument('--sum', dest='accumulate', action='store_const',     #添加一个可选参数
                    const=sum, default=max,
                    help='sum the integers (default: find the max)')

args = parser.parse_args()                                                #解析参数
print(args)
print(args.integers)
print(args.accumulate(args.integers))

>>>    #cmd运行中
PS C:\Users\root> python3 D:\test\python\test\hh.py 1 2 3 4 --sum 
<<<    #结果输出
Namespace(accumulate=<built-in function sum>, integers=[1, 2, 3, 4])
[1, 2, 3, 4]
10

2、ArgumentParser对象

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)

  • prog:程序的名称(默认值:sys.argv[0])
  • usage:描述程序的使用方法(默认值:从添加到解析器的参数生成)
  • description:在参数帮助文档之前显示的文本(默认值:无)
  • epilog:在参数帮助文档之后显示的文本(默认值:无)
  • parents:一个 ArgumentParser 对象的列表,它们的参数也应包含在内
  • formatter_class:用于自定义帮助文档输出格式的类
  • prefix_chars:可选参数的前缀字符集合(默认值: '-')
  • fromfile_prefix_chars:当需要从文件中读取其他参数时,用于标识文件名的前缀字符集合(默认值: None)
  • argument_default:参数的全局默认值(默认值: None)
  • conflict_handler:解决冲突选项的策略(通常是不必要的)
  • add_help:为解析器添加一个 -h/--help 选项(默认值: True)
  • allow_abbrev:如果缩写是无歧义的,则允许缩写长选项 (默认值:True)

1、prog:程序名称

  • 默认情况下,程序名称使用sys.argv[0]的值。
  • 程序名称可以在帮助信息中通过%(prog)s格式说明符来引用。
import argparse
parser = argparse.ArgumentParser()
# parser = argparse.ArgumentParser(prog='myprogram')
parser.add_argument('--foo', help='foo of the %(prog)s program')
args = parser.parse_args()

>>>
PS D:\test\python> python3 D:\test\python\test\hh.py -h  
<<<
usage: hh.py [-h] [--foo FOO]                         #注意,程序名称

optional arguments:
  -h, --help  show this help message and exit
  --foo FOO   foo of the hh.py program                #注意,程序名称引用

2、usage:脚本的用法说明

  • 自定义程序的使用方法。
import argparse
parser = argparse.ArgumentParser(prog='PROG', usage='%(prog)s [options]')
parser.add_argument('--foo', nargs='?', help='foo help')
parser.add_argument('bar', nargs='+', help='bar help')
parser.print_help()

<<<
PS D:\test\python> python3 D:\test\python\test\hh.py -h  
>>>
usage: PROG [options]                                 #注意,自定义程序使用说明

positional arguments:
  bar          bar help

optional arguments:
  -h, --help   show this help message and exit
  --foo [FOO]  foo help

3、description:文档前的说明信息

  • 在帮助文档之前,简要描述这个程序做什么以及怎么做。
  • 在帮助消息中,这个描述会显示在命令行用法字符串和各种参数的帮助消息之间。
  • 默认会换行,可以使用formatter_class参数改变。
import argparse
parser = argparse.ArgumentParser(description='A foo that bars')
parser.print_help()

>>>
PS D:\test\python> python3 D:\test\python\test\hh.py -h
<<<
usage: hh.py [-h]

A foo that bars                                        #注意,description

optional arguments:
  -h, --help  show this help message and exit

4、epilog:文档后的说明信息

  • 在帮助文档之后显示。
  • 默认会换行,可以使用formatter_class参数改变。
import argparse
parser = argparse.ArgumentParser(description='A foo that bars', epilog="And that's how you'd foo a bar")
parser.print_help()

>>>
PS D:\test\python> python3 D:\test\python\test\hh.py -h   
<<<
usage: hh.py [-h]

A foo that bars                                       #注意,description

optional arguments:
  -h, --help  show this help message and exit

And that's how you'd foo a bar                        #注意,epilog

5、parents:父子解析器

  • 在通过parents=传递解析器之前,必须完全初始化它们。
  • 如果在子解析器之后更改父解析器,这些更改将不会反映在子解析器中。
import argparse
parent_parser = argparse.ArgumentParser(add_help=False)          #定义父解析器
parent_parser.add_argument('--parent', type=int)

foo_parser = argparse.ArgumentParser(parents=[parent_parser])    #定义子解析器,注意parents的值是父解析器对象[parent_parser]
foo_parser.add_argument('foo')
print(foo_parser.parse_args())
print(foo_parser.parse_args(['XXX']))

bar_parser = argparse.ArgumentParser(parents=[parent_parser])    #定义子解析器,注意parents的值是父解析器对象[parent_parser]
bar_parser.add_argument('--bar')
print(bar_parser.parse_args(['--bar', 'YYY']))

>>>
PS D:\test\python> python3 D:\test\python\test\hh.py 'fff' --parent 2
<<<
Namespace(foo='fff', parent=2)
Namespace(foo='XXX', parent=None)
Namespace(bar='YYY', parent=None)

6、formatter_class:帮助信息的格式

  • formatter_class定义description和epilog的格式,它的值是四个类:
    • class argparse.RawDescriptionHelpFormatter
      • 表示description和epilog已经被正确的格式化了,不能在命令行中被自动换行
      • 多个连续空格:description和epilog中的全部被保留,参数描述中的只保留一个。多个连续空行只保留一个,如果想保留多重的空白行,可以在空行中加空格。
    • class argparse.RawTextHelpFormatter
      • 表示description和epilog已经被正确的格式化了,不能在命令行中被自动换行
      • 多个连续空格:全部被保留(description、epilog和参数描述中的空格)。多个连续空行只保留一个,如果想保留多重的空白行,可以在空行中加空格。
    • class argparse.ArgumentDefaultsHelpFormatter
      • 参数的帮助信息中会添加默认值
    • class argparse.MetavarTypeHelpFormatter
      • 参数的帮助信息中会使用type的值当作它的显示名
      • 每一个参数都要有type,否则异常
    • 不设置formatter_class
      • 默认情况下,ArgumentParser对象会将description和epilog的文字在命令行中自动换行。
import argparse
parser = argparse.ArgumentParser(
    prog='PROG',
    #
    formatter_class=argparse.RawDescriptionHelpFormatter,
    # formatter_class=argparse.RawTextHelpFormatter,
    # formatter_class=argparse.ArgumentDefaultsHelpFormatter,
    # formatter_class=argparse.MetavarTypeHelpFormatter,
    description='''    this description
was indented weird      but that is okay''',
    epilog='''    likewise for this epilog whose whitespace will
be cleaned up and whose words will be wrapped


         across a couple     lines''')
parser.add_argument('--foo', type=int, default=42, help='FO   O!')
parser.add_argument('bar', type=float, nargs='*', default=[1, 2, 3], help='BA   R!')    #type=float是后加的,否则formatter_class=argparse.RawTextHelpFormatter时会异常
parser.print_help()

>>>
PS C:\Users\root> python3 D:\test\python\test\hh.py
<<<                                           #默认,不设置formatter_class参数
usage: PROG [-h] [--foo FOO] [bar [bar ...]]

this description was indented weird but that is okay

positional arguments:
  bar         BA R!

optional arguments:
  -h, --help  show this help message and exit
  --foo FOO   FO O!

likewise for this epilog whose whitespace will be cleaned up and whose
words will be wrapped across a couple lines
<<<                                           #formatter_class=argparse.RawDescriptionHelpFormatter
usage: PROG [-h] [--foo FOO] [bar [bar ...]]

    this description
was indented weird      but that is okay

positional arguments:
  bar         BA R!

optional arguments:
  -h, --help  show this help message and exit
  --foo FOO   FO O!

    likewise for this epilog whose whitespace will
be cleaned up and whose words will be wrapped

         across a couple     lines
<<<                                           #formatter_class=argparse.RawTextHelpFormatter
usage: PROG [-h] [--foo FOO] [bar [bar ...]]

    this description
was indented weird      but that is okay

positional arguments:
  bar         BA   R!

optional arguments:
  -h, --help  show this help message and exit
  --foo FOO   FO   O!

    likewise for this epilog whose whitespace will
be cleaned up and whose words will be wrapped

         across a couple     lines
<<<                                           #formatter_class=argparse.ArgumentDefaultsHelpFormatter
usage: PROG [-h] [--foo FOO] [bar [bar ...]]

this description was indented weird but that is okay

positional arguments:
  bar         BA R! (default: [1, 2, 3])

optional arguments:
  -h, --help  show this help message and exit
  --foo FOO   FO O! (default: 42)

likewise for this epilog whose whitespace will be cleaned up and whose
words will be wrapped across a couple lines
<<<                                           #formatter_class=argparse.MetavarTypeHelpFormatter
usage: PROG [-h] [--foo int] [float [float ...]]

this description was indented weird but that is okay

positional arguments:
  float       BA R!

optional arguments:
  -h, --help  show this help message and exit
  --foo int   FO O!

likewise for this epilog whose whitespace will be cleaned up and whose
words will be wrapped across a couple lines

7、prefix_chars:命令行参数的前缀

  • 命令行参数默认使用 '-'当作前缀。
  • 如果解析器需要支持不同的或者额外的字符,比如像+f或者/foo的选项,可以在参数解析构建器中使用prefix_chars。
import argparse
parser = argparse.ArgumentParser(prog='PROG', prefix_chars='-+')
parser.add_argument('+f')
parser.add_argument('++bar')
print(parser.parse_args())

>>>
PS C:\Users\root> python3 D:\test\python\test\hh.py +f hh ++bar bbb
<<<
Namespace(bar='bbb', f='hh')

8、fromfile_prefix_chars:参数与文件

  • 当处理一个特别长的命令行参数列表的时候,将其放在文件中会更方便。(将命令行参数放在文件中
  • 从文件读取的参数在默认情况下必须一个一行,并且与命令行上的原始文件引用参数位于同一位置。
    • 重复的参数,位于后面的生效
  • 默认fromfile_prefix_chars = None,意味着参数不会被当作文件对待。
import argparse
with open('args.txt', 'w') as fp:
    fp.write('-a\naaa\n-f\nfff')
parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
parser.add_argument('-a')
parser.add_argument('-f')
parser.add_argument('--bar')
print(parser.parse_args(['-f', 'FFF', '@args.txt', '-a', 'AAA', '--bar', 'BBB']))

<<<
Namespace(a='AAA', bar='BBB', f='fff')
  • 例如,['-f', 'FFF', '@args.txt', '-a', 'AAA', '--bar', 'BBB']等价于['-f', 'FFF', '-a', 'aaa', '-f', 'fff', '-a', 'AAA', '--bar', 'BBB']

9、argument_default

import argparse
parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)
parser.add_argument('--foo',default=[1, 2, 3])
parser.add_argument('bar', nargs='?')
print(parser.parse_args(['--foo', '1', 'BAR']))
print(parser.parse_args([])

<<<
Namespace(bar='BAR', foo='1')
Namespace(foo=[1, 2, 3])           #默认的输出是:Namespace(bar=None, foo=[1, 2, 3])

10、allow_abbrev:长选项的缩写

  • 默认情况下,可以使用长选项的缩写
  • allow_abbrev=False,禁止长选项使用缩写。
import argparse
parser = argparse.ArgumentParser(prog='PROG', allow_abbrev=False)
parser.add_argument('--foobar', action='store_true')
parser.add_argument('--foonley', action='store_false')
print(parser.parse_args(['--foon']))

<<<
usage: PROG [-h] [--foobar] [--foonley]
PROG: error: unrecognized arguments: --foon

11、conflict_handler:重写命令行参数

  • 默认情况下,在相同选项下不允许有两种行为。
  • conflict_handler='resolve',重写旧的相同选项
import argparse
parser = argparse.ArgumentParser(prog='PROG', conflict_handler='resolve')
parser.add_argument('-f', '--foo', help='old foo help')    #有两个--foo选项
parser.add_argument('-d', '--foo', help='new foo help')
print(parser.parse_args(['-d', 'fff']))                    #注意,这里用的短选项-d

<<<
Namespace(foo='fff')

12、add_help:-h/--help

  • 默认情况下,帮助信息会有"-h, --help show this help message and exit"
  • add_help=False,可以禁止在命令行中使用-h/--help,并禁止帮助信息中显示"-h, --help show this help message and exit"

示例1:默认

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', help='foo help')
args = parser.parse_args()

>>>
PS C:\Users\root> python3 D:\test\python\test\hh.py -h
<<<
usage: hh.py [-h] [--foo FOO]

optional arguments:
  -h, --help  show this help message and exit
  --foo FOO   foo help

示例2:add_help=False

import argparse
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument('--foo', help='foo help')
parser.print_help()
args = parser.parse_args()

>>>
PS C:\Users\root> python3 D:\test\python\test\hh.py --help
<<<
usage: hh.py [--foo FOO]

optional arguments:
  --foo FOO  foo help
usage: hh.py [--foo FOO]
hh.py: error: unrecognized arguments: --help

3、add_argument()方法

  • 定义单个的命令行参数应当如何解析。

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

  • name or flags:选项名称或选项字符串的列表,例如 foo 或 -f, --foo。
  • action:当参数在命令行中出现时使用的动作。
  • nargs:命令行参数应当消耗的数目。
  • const:被一些 action 和 nargs 选择所需求的常数。
  • default:当参数未在命令行中出现时使用的值。
  • type:命令行参数应当被转换成的数据类型。
  • choices:可用的参数的容器。
  • required:此命令行参数是否可省略 (仅选项可用)。
  • help:此参数作用的简单描述。
  • metavar:在使用方法消息中使用的参数值示例。
  • dest:被添加到 parse_args() 所返回对象上的属性名(即参数名)。

1、name or flags:参数名称

  • 可选参数:带参数前缀的是可选参数,例如 -f 或 --foo,(长短参数。没有默认值时,可缺省,其值是None)
  • 位置参数:不带参数前缀的是位置参数,例如 bar(必须参数。没有默认值时,不可缺省)
  • 当parse_args()被调用,长短参数会以 - 前缀识别,剩下的参数则会被假定为位置参数
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo')
parser.add_argument('--zoo')
parser.add_argument('bar')
parser.add_argument('par')
print(parser.parse_args())

>>>
PS C:\Users\root> python3 D:\test\python\test\hh.py --foo fff bbb ppp 
<<<
Namespace(bar='bbb', foo='fff', par='ppp', zoo=None)

2、action:参数的动作

  • action指定了这个命令行参数出现时应当如何处理。
  • action的值可以是:
    • 'store':存储参数的值。这是默认的动作
    • 'store_const':存储被const指定的值。
    • 'store_true':等价于'store_const'存储True,且默认值分别为False
    • 'store_false':等价于'store_const'存储False,且默认值分别为True。
    • 'append':存储一个列表,并且将每个参数值追加到列表中。允许同一个参数多次使用
    • 'append_const':这存储一个列表,并将const指定的值追加到列表中(注意const的值默认是None。)。一般在多个参数需要在同一列表中存储常数时会有用。
    • 'extend':这会存储一个列表,并将每个参数值加入到列表中。
    • 'count':计算一个关键字参数出现的数目或次数
    • 'help':打印所有当前解析器中的选项和参数的完整帮助信息,然后退出。默认情况下,一个 help 动作会被自动加入解析器
    • 'version':期望有一个 version= 命名参数在 add_argument() 调用中,并打印版本信息并在调用后退出
    • 自定义

1、store

  • 默认动作,存储参数的值。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo')
print(parser.parse_args('--foo 1'.split()))

<<<
Namespace(foo='1')

2、store_const

  • 存储被const指定的值。
  • 该命令行参数出现时其值被固定,即不能再为其赋值,否则异常。
  • 用于可选参数。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', action='store_const', const=42)
print(parser.parse_args(['--foo']))

<<<
Namespace(foo=42)

3、store_true和store_false

  • 'store_true':等价于'store_const'存储True,且默认值分别为False
  • 'store_false':等价于'store_const'存储False,且默认值分别为True。
  • 用于可选参数。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', action='store_true')
parser.add_argument('--bar', action='store_false')
parser.add_argument('--baz', action='store_false')
print(parser.parse_args('--foo --bar'.split()))

<<<
Namespace(bar=False, baz=True, foo=True)

4、append

  • 存储一个列表,并且将每个参数值追加到列表中。
  • 允许同一个参数多次使用
  • 用于可选参数
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', action='append')
print(parser.parse_args('--foo 1 --foo 2 '.split()))

<<<
Namespace(foo=['1', '2'])

5、append_const

  • 存储一个列表,并将const指定的值添加到列表中。(注意const关键字参数默认为None。)
  • 多个参数需要将常量存储到同一个列表中时,append_const通常很有用。必须与dest一起使用
  • 用于可选参数。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--str', dest='types', action='append_const', const=str)
parser.add_argument('--int', dest='types', action='append_const', const=int)
print(parser.parse_args('--str --int'.split()))

<<<
Namespace(types=[<class 'str'>, <class 'int'>])

6、extend

  • 存储一个列表,并将每个参数值加入到列表中。
  • 用于可选参数
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--foo", action="extend", nargs="+", type=str)
print(parser.parse_args(["--foo", "f1", "--foo", "f2", "f3", "f4"]))

<<<
Namespace(foo=['f1', 'f2', 'f3', 'f4'])

7、count

  • 计算一个关键字参数出现的数目或次数。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--verbose', '-v', action='count', default=0)    #default将为None,除非显式地设为0
print(parser.parse_args(['-vvv']))

<<<
Namespace(verbose=3)

8、help

  • 给参数添加帮助信息
  • 默认情况下,一个 help 动作会被自动加入解析器
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--verbose', '-v', action='count', default=0, help='v出现的次数')
parser.parse_args()

>>>
PS C:\Users\root> python3 D:\test\python\test\hh.py -h
<<<
usage: hh.py [-h] [--verbose]

optional arguments:
  -h, --help     show this help message and exit
  --verbose, -v  v出现的次数

9、version

  • 在add_argument()调用中需要一个version=关键字参数,打印版本信息并在调用时退出
import argparse
parser = argparse.ArgumentParser(prog='PROG')
parser.add_argument('--version', action='version', version='%(prog)s 2.0')
parser.parse_args(['--version'])

<<<
PROG 2.0

3、nargs:设定参数的参数值数量

  • ArgumentParser对象通常将一个命令行参数值关联到到一个命令行参数。
  • nargs可以将不同数目的命令行参数值关联到到一个命令行参数。
  • nargs的值有:
    • N:一个整数,一个参数关联多个参数值
    • '?':一个参数关联一个参数值
    • '*':一个参数关联多个参数值
    • '+':一个参数关联多个参数值
    • argarse.REMAINDER:将剩余所有的命令行参数值聚集到一个列表中

1、N:一个整数,一个参数关联多个参数值

  • 命令行中的N个参数被聚集到一个列表中。
  • 注意nargs=1会产生一个单元素列表。这和默认的元素本身是不同的。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', nargs=1)
parser.add_argument('bar', nargs=2)
print(parser.parse_args('c v --foo b'.split()))

<<<
Namespace(bar=['c', 'v'], foo=['b'])

2、?:一个参数关联一个参数值

  • 将一个命令行参数值关联到到一个命令行参数。
    • 可选参数:
      • 有参数和参数值,参数的值是参数值;
      • 仅有参数,没有参数值,参数的值是const的值;
      • 既无参数,也无参数值,参数的值是default的值
    • 位置参数:没有值,使用default的值
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', nargs='?', const='c', default='d')
parser.add_argument('bar', nargs='?', default='d')
print(parser.parse_args(['XX', '--foo', 'YY']))
print(parser.parse_args(['XX', '--foo']))
print(parser.parse_args([]))

<<<
Namespace(bar='XX', foo='YY')
Namespace(bar='XX', foo='c')
Namespace(bar='d', foo='d')
  • 通常用法是允许可选的输入或输出文件
import argparse
import sys
parser = argparse.ArgumentParser()
parser.add_argument('infile', nargs='?', type=argparse.FileType('r'), default=sys.stdin)
parser.add_argument('outfile', nargs='?', type=argparse.FileType('w'), default=sys.stdout)
print(parser.parse_args(['args.txt', 'args.txtt']))
print(parser.parse_args([]))

<<<
Namespace(infile=<_io.TextIOWrapper name='args.txt' mode='r' encoding='cp936'>, outfile=<_io.TextIOWrapper name='args.txtt' mode='w' encoding='cp936'>)
Namespace(infile=<_io.TextIOWrapper name='<stdin>' mode='r' encoding='utf-8'>, outfile=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>)

3、*:一个参数关联多个参数值

  • 当前命令行参数值被聚集到一个列表中。
  • 注意:多个位置参数通常没有意义,但是多个选项是可能的。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', nargs='*')
parser.add_argument('--bar', nargs='*')
parser.add_argument('baz', nargs='*')
print(parser.parse_args('a b --foo x y --bar 1 2'.split()))

<<<
Namespace(bar=['1', '2'], baz=['a', 'b'], foo=['x', 'y'])

4、'+':一个参数关联多个参数值

  • 当前命令行参数值被聚集到一个列表中。
  • 和 '*' 类似,但至少要有一个参数值,否则异常。
import argparse
parser = argparse.ArgumentParser(prog='PROG')
parser.add_argument('foo', nargs='+')
print(parser.parse_args(['a', 'b']))
print(parser.parse_args([]))

<<<
Namespace(foo=['a', 'b'])

usage: PROG [-h] foo [foo ...]
PROG: error: the following arguments are required: foo

5、argarse.REMAINDER:将剩余所有的命令行参数值聚集到一个列表中

  • 通常在从一个命令行传递参数到另一个命令行中时有用。
import argparse
parser = argparse.ArgumentParser(prog='PROG')
parser.add_argument('--foo')
parser.add_argument('command')
parser.add_argument('args', nargs=argparse.REMAINDER)
print(parser.parse_args('--foo B cmd --arg1 XX ZZ'.split()))

<<<
Namespace(args=['--arg1', 'XX', 'ZZ'], command='cmd', foo='B')

4、const

  • action='store_const'或action='append_const时,const必须给出。
  • 可选参数并且nargs='?'时,可能需要const。

5、default:参数默认值

  • default值在参数未在命令行中出现时使用。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', default=42)
print(parser.parse_args(['--foo', '2']))
print(parser.parse_args([]))

<<<
Namespace(foo='2')
Namespace(foo=42)
  • 如果默认值是一个字符串,解析器解析该值时就像它是一个命令行参数一样。
  • 如果提供了任何类型转换参数,解析器将在设置Namespace返回值上的属性之前应用该参数。否则,解析器按如下方式使用该值:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--length', default='10', type=int)
parser.add_argument('--width', default=10.5, type=int)
print(parser.parse_args([]))

<<<
Namespace(length=10, width=10.5)

6、type:参数值的数据类型

  • 默认情况下,ArgumentParser对象将命令行参数当作简单字符串读入。
  • type允许任何的类型检查和类型转换。
  • 一般的内建类型和函数可以直接当作type的值。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('foo', type=int)
parser.add_argument('bar', type=open)
print(parser.parse_args('2 temp.txt'.split()))

<<<
Namespace(bar=<_io.TextIOWrapper name='temp.txt' mode='r' encoding='cp936'>, foo=2)
  • 为方便使用不同类型的文件,argparse模块提供了FileType工厂类,该类接受 mode=, bufsize=, encoding= 和 errors= 等 open() 函数参数。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('bar', type=argparse.FileType('w'))
print(parser.parse_args(['out.txt']))

<<<
Namespace(bar=<_io.TextIOWrapper name='out.txt' mode='w' encoding='cp936'>)
  • 可接受任意可调用对象,该对象应传入单个字符串参数并返回转换后的值
import argparse
import math
def perfect_square(string):
    value = int(string)
    sqrt = math.sqrt(value)
    if sqrt != int(sqrt):
        msg = "%r is not a perfect square" % string
        raise argparse.ArgumentTypeError(msg)
    return value

parser = argparse.ArgumentParser(prog='PROG')
parser.add_argument('foo', type=perfect_square)
print(parser.parse_args(['9']))
print(parser.parse_args(['7']))

<<<
Namespace(foo=9)
usage: PROG [-h] foo
PROG: error: argument foo: '7' is not a perfect square

7、choices:参数的枚举值

  • 应该从一组受限制的值中选择命令行参数值。
  • 当命令行被解析时,参数值将被检查,如果参数不是可接受值之一,将显示一个错误消息。
  • 任何容器都可作为choices值传入,因此list对象set对象以及自定义容器都是受支持的。
import argparse
parser = argparse.ArgumentParser(prog='game.py')
parser.add_argument('move', choices=['rock', 'paper', 'scissors'])
print(parser.parse_args(['rock']))
print(parser.parse_args(['fire']))

<<<
Namespace(move='rock')
usage: game.py [-h] {rock,paper,scissors}
game.py: error: argument move: invalid choice: 'fire' (choose from 'rock', 'paper', 'scissors')
  • 命令行参数值被type转换后,才会与choices的值进行匹配。因此choices容器中对象的类型应当与指定的type相匹配。
import argparse
parser = argparse.ArgumentParser(prog='doors.py')
parser.add_argument('door', type=int, choices=range(1, 4))
print(parser.parse_args(['3']))
print(parser.parse_args(['4']))

<<<
Namespace(door=3)
usage: doors.py [-h] {1,2,3}
doors.py: error: argument door: invalid choice: 4 (choose from 1, 2, 3)

8、required:可选参数是否为必需的

  • required=True,将可选参数设置为必需的
  • 注解:必需的选项通常被认为是不适宜的,因为用户会预期options都是可选的,因此在可能的情况下应当避免使用它们。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', required=True)
print(parser.parse_args(['--foo', 'BAR']))
print(parser.parse_args([]))

<<<
Namespace(foo='BAR')
usage: hh.py [-h] --foo FOO
hh.py: error: the following arguments are required: --foo

9、dest:arse_args返回的参数名

  • 对于位置参数,dest的值就是位置参数本身。 
  • 对于可选参数,dest的值通常取自选项字符串。
    • ArgumentParser会通过接受第一个长选项字符串并去掉开头的 -- 字符串来生成dest的值。
    • 如果没有提供长选项字符串,则dest将通过接受第一个短选项字符串并去掉开头的 - 字符来获得。
    • 任何内部的 - 字符都将被转换为字符以确保字符串是有效的属性名称。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('bar')
parser.add_argument('-f', '--foo-bar', '--foo')
parser.add_argument('-x', '-y')
print(parser.parse_args('-f 1 -x 2 bbb'.split()))
print(parser.parse_args('bbb --foo 1 -y 2'.split()))

<<<
Namespace(bar='bbb', foo_bar='1', x='2')
Namespace(bar='bbb', foo_bar='1', x='2')
  • dest允许提供自定义属性名称。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', dest='bar')
print(parser.parse_args('--foo XXX'.split()))

<<<
Namespace(bar='XXX')

10、metavar:参数帮助信息

  • 当ArgumentParser生成帮助消息时,它需要以某种方式引用每个期望的参数值。
  • 默认情况下,对于位置参数操作,dest值是直接使用的,对于可选参数操作,dest值是大写的。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo')
parser.add_argument('bar')
parser.parse_args('X --foo Y'.split())
parser.print_help()

<<<
usage: hh.py [-h] [--foo FOO] bar

positional arguments:
  bar

optional arguments:
  -h, --help  show this help message and exit
  --foo FOO
  • 请注意metavar仅改变帮助信息的显示名称。parse_args()对象的属性名称仍然会由dest值确定。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', metavar='YYY')
parser.add_argument('bar', metavar='XXX')
parser.parse_args('X --foo Y'.split())
parser.print_help()

<<<
usage: hh.py [-h] [--foo YYY] XXX

positional arguments:
  XXX

optional arguments:
  -h, --help  show this help message and exit
  --foo YYY
  • 不同的nargs值可能导致metavar被多次使用。 提供一个元组给metavar即为每个参数指定不同的显示信息。
import argparse
parser = argparse.ArgumentParser(prog='PROG')
parser.add_argument('-x', nargs=2)
parser.add_argument('--foo', nargs=2, metavar=('bar', 'baz'))
parser.print_help()

<<<
usage: PROG [-h] [-x X X] [--foo bar baz]

optional arguments:
  -h, --help     show this help message and exit
  -x X X
  --foo bar baz

11、help:参数作用的简单描述

  • help字符串可包括各种格式描述符以避免重复使用程序名称或参数等文本。
  • 有效的描述符包括程序名称 %(prog)s 和传给 add_argument() 的大部分关键字参数,例如 %(default)s, %(type)s 等等。
import argparse
parser = argparse.ArgumentParser(prog='frobble')
parser.add_argument('bar', nargs='?', type=int, default=42,
                    help='the bar to %(prog)s (default: %(default)s)')
parser.print_help()

<<<
usage: frobble [-h] [bar]

positional arguments:
  bar         the bar to frobble (default: 42)

optional arguments:
  -h, --help  show this help message and exit

4、parse_args()方法

  • 将参数字符串转换为对象,并将其设为命名空间的属性。 返回带有成员的命名空间。

ArgumentParser.parse_args(args=None, namespace=None)

  • args:要解析的字符串列表。 默认值是从 sys.argv 获取。
  • namespace:用于获取属性的对象。 默认值是一个新的空 Namespace 对象。

1、选项值语法

  • 可选参数的参数和参数值可以作为两个单独参数传入。
  • 对于长选项,参数和参数值可以作为单个命令行参数传入,使用 = 分隔它们。
  • 对于短选项,参数和参数值可以拼接在一起。
import argparse
parser = argparse.ArgumentParser(prog='PROG')
parser.add_argument('-x')
parser.add_argument('--foo')
parser.add_argument('bar')
print(parser.parse_args(['--foo', 'FOO', '-x', 'X', 'bar']))
print(parser.parse_args(['--foo=FOO', '-xX', 'bar']))

<<<
Namespace(bar='bar', foo='FOO', x='X')
Namespace(bar='bar=bar', foo='FOO', x='X')

2、无效的参数

  • 在解析命令行时,parse_args() 会检测多种错误,包括有歧义的选项、无效的类型、无效的选项、错误的位置参数个数等等。
  • 当遇到这种错误时,它将退出并打印出错误文本同时附带用法消息。
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo', type=int)
>>> parser.add_argument('bar', nargs='?')

>>> # invalid type
>>> parser.parse_args(['--foo', 'spam'])
usage: PROG [-h] [--foo FOO] [bar]
PROG: error: argument --foo: invalid int value: 'spam'

>>> # invalid option
>>> parser.parse_args(['--bar'])
usage: PROG [-h] [--foo FOO] [bar]
PROG: error: no such option: --bar

>>> # wrong number of arguments
>>> parser.parse_args(['spam', 'badger'])
usage: PROG [-h] [--foo FOO] [bar]
PROG: error: extra arguments found: badger

3、包含 - 的参数

  • 当短参数看起来像负数时,解析器会将命令行中所有的负数参数解析为短参数。
  • 位置参数只有是负数并且解析器中没有任何选项看起来像负数时,位置参数才能以 - 打头。
import argparse
parser = argparse.ArgumentParser(prog='PROG')
parser.add_argument('-1', dest='one')
parser.add_argument('foo', nargs=1)
parser.add_argument('bar', nargs=1)
print(parser.parse_args(['-1', 'X', '-2', '-3']))   #'-2','-3'也被解析为短参数

<<<
usage: PROG [-h] [-1 ONE] foo bar
PROG: error: the following arguments are required: foo, bar
  • 如果必须使用以 - 打头的位置参数,可以插入伪参数 '--' 告诉parse_args()在那之后的内容是位置参数
import argparse
parser = argparse.ArgumentParser(prog='PROG')
parser.add_argument('-1', dest='one')
parser.add_argument('foo', nargs=1)
parser.add_argument('bar', nargs=1)
print(parser.parse_args(['-1', 'X', '--', '-2', '-3']))

<<<
Namespace(bar=['-3'], foo=['-2'], one='X')

4、参数缩写(前缀匹配)

  • parse_args()方法在默认情况下允许将长选项缩写为前缀,如果缩写无歧义(即前缀与一个特定选项相匹配)的话
import argparse
parser = argparse.ArgumentParser(prog='PROG')
parser.add_argument('-bacon')
parser.add_argument('-badger')
print(parser.parse_args('-bac MMM'.split()))
print(parser.parse_args('-bad WOOD'.split()))
print(parser.parse_args('-ba BA'.split()))       #因歧义,异常

<<<
Namespace(bacon='MMM', badger=None)
Namespace(bacon=None, badger='WOOD')

usage: PROG [-h] [-bacon BACON] [-badger BADGER]
PROG: error: ambiguous option: -ba could match -bacon, -badger

5、FileType对象

class argparse.FileType(mode='r', bufsize=-1, encoding=None, errors=None)

  • FileType工厂类用于创建可作为ArgumentParser.add_argument()的type参数传入的对象。
  • 以FileType对象作为其类型的参数将使用命令行参数以所请求模式、缓冲区大小、编码格式和错误处理方式打开文件
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--raw', type=argparse.FileType('wb', 0))
parser.add_argument('out', type=argparse.FileType('w', encoding='UTF-8'))
print(parser.parse_args(['--raw', 'raw.dat', 'file.txt']))

<<<
Namespace(out=<_io.TextIOWrapper name='file.txt' mode='w' encoding='UTF-8'>, raw=<_io.FileIO name='raw.dat' mode='wb' closefd=True>)
  • FileType 对象能理解伪参数 '-' 并会自动将其转换为 sys.stdin 用于可读的 FileType 对象,或是 sys.stdout 用于可写的 FileType 对象:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--raw', type=argparse.FileType('wb', 0))
parser.add_argument('out', type=argparse.FileType('r', encoding='UTF-8'))
print(parser.parse_args(['--raw', '-', '-']))

<<<
Namespace(out=<_io.TextIOWrapper name='<stdin>' mode='r' encoding='utf-8'>, raw=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>)

6、互斥

ArgumentParser.add_mutually_exclusive_group(required=False)

  • 创建一个互斥组。 argparse 将会确保互斥组中只有一个参数在命令行中可用
import argparse
parser = argparse.ArgumentParser(prog='PROG')
group = parser.add_mutually_exclusive_group()
group.add_argument('--foo', action='store_true')
group.add_argument('--bar', action='store_false')
print(parser.parse_args(['--foo']))
print(parser.parse_args(['--bar']))
print(parser.parse_args(['--foo', '--bar']))     #因互斥,异常

<<<
Namespace(bar=True, foo=True)
Namespace(bar=False, foo=False)

usage: PROG [-h] [--foo | --bar]
PROG: error: argument --bar: not allowed with argument --foo
  • add_mutually_exclusive_group() 方法也接受一个 required 参数,表示在互斥组中至少有一个参数是需要的
import argparse
parser = argparse.ArgumentParser(prog='PROG')
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('--foo', action='store_true')
group.add_argument('--bar', action='store_false')
print(parser.parse_args([]))     #异常

<<<
usage: PROG [-h] (--foo | --bar)
PROG: error: one of the arguments --foo --bar is required

7、打印帮助

  • ArgumentParser.print_usage(file=None)
    • 打印一段简短描述,说明应当如何在命令行中发起调用 ArgumentParser。 如果 file 为 None,则默认使用 sys.stdout。
  • ArgumentParser.print_help(file=None)
    • 打印一条帮助消息,包括程序用法和通过 ArgumentParser 注册的相关参数信息。 如果 file 为 None,则默认使用 sys.stdout。
  • ArgumentParser.format_usage()
    • 返回一个包含简短描述的字符串,说明应当如何在命令行中发起调用 ArgumentParser。
  • ArgumentParser.format_help()
    • 反回一个包含帮助消息的字符串,包括程序用法和通过 ArgumentParser 注册的相关参数信息。

8、退出方法

  • ArgumentParser.exit(status=0, message=None)
    • 此方法将终结程序,退出时附带指定的 status,并且如果给出了 message 则会在退出前将其打印输出
  • ArgumentParser.error(message)
    • 此方法将向标准错误打印包括 message 的用法消息并附带状态码 2 终结程序。

 

posted @ 2021-06-27 05:54  麦恒  阅读(595)  评论(0编辑  收藏  举报