前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >argparse------用于命令行选项、参数和子命令的解析器

argparse------用于命令行选项、参数和子命令的解析器

作者头像
狼啸风云
修改2022-09-03 21:48:46
6.8K0
修改2022-09-03 21:48:46
举报

目录

创建一个解析器

添加参数

解析参数

ArgumentParser对象

prog

usage

描述

epilog

parents

formatter_class

prefix_chars

fromfile_prefix_chars

argument_default

allow_abbrev

conflict_handler

add_help

The add_argument() 函数

name or flags

action

nargs

const

default

type

choices

required

help

metavar

dest

Action类

The parse_args() method

Option value syntax

Invalid arguments

Arguments containing -

Argument缩减

Beyond sys.argv

The Namespace object

Other utilities

Sub-commands

FileType objects

Argument groups

Mutual exclusion

Parser defaults

Printing help

Partial parsing

Customizing file parsing

Exiting methods

Intermixed parsing

Upgrading optparse code


argparse模块使编写用户友好的命令行界面变得很容易。程序定义了它需要什么参数,argparse将找出如何从sys.argv中解析这些参数。argparse模块还自动生成帮助和使用消息,并在用户给程序提供无效参数时发出错误。

下面的代码是一个Python程序,它接受一个整数列表,并产生和或最大值:

代码语言:javascript
复制
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.accumulate(args.integers))

假设上面的Python代码保存到一个名为prog的文件中。,它可以在命令行运行,并提供有用的帮助信息:

代码语言:javascript
复制
$ python prog.py -h
usage: prog.py [-h] [--sum] N [N ...]

Process some integers.

positional arguments:
 N           an integer for the accumulator

optional arguments:
 -h, --help  show this help message and exit
 --sum       sum the integers (default: find the max)

当使用适当的参数运行时,它输出命令行整数的和或最大值:

代码语言:javascript
复制
$ python prog.py 1 2 3 4
4

$ python prog.py 1 2 3 4 --sum
10

如果传入无效参数,则会发出错误:

代码语言:javascript
复制
$ python prog.py a b c
usage: prog.py [-h] [--sum] N [N ...]
prog.py: error: argument N: invalid int value: 'a'

下面的部分将带您了解这个示例。

创建一个解析器

使用argparse的第一步是创建一个ArgumentParser对象:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser(description='Process some integers.')

ArgumentParser对象将保存将命令行解析为Python数据类型所需的所有信息。

添加参数

通过调用add_argument()方法,可以用关于程序参数的信息填充ArgumentParser。通常,这些调用告诉ArgumentParser如何获取命令行上的字符串并将它们转换成对象。当调用parse_args()时,将存储并使用此信息。例如:

代码语言:javascript
复制
>>> 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)')

稍后,调用parse_args()将返回一个具有整数和累加两个属性的对象。integers属性将是一个或多个int的列表,而累加属性将是sum()函数(如果——sum在命令行中指定),或者max()函数(如果没有)。

解析参数

ArgumentParser通过parse_args()方法解析参数。这将检查命令行,将每个参数转换为适当的类型,然后调用适当的操作。在大多数情况下,这意味着一个简单的命名空间对象将建立从命令行解析的属性:

代码语言:javascript
复制
>>> parser.parse_args(['--sum', '7', '-1', '42'])
Namespace(accumulate=<built-in function sum>, integers=[7, -1, 42])

在脚本中,parse_args()通常没有参数,ArgumentParser将自动确定sys.argv中的命令行参数。

ArgumentParser对象

代码语言:javascript
复制
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)

创建一个新的ArgumentParser对象。所有参数都应该作为关键字参数传递。每一个参数都有其更详细的描述如下,但简而言之,它们是:

  • prog - 程序名称(默认:sys.argv[0])
  • usage - 描述程序使用情况的字符串(默认值:由添加到解析器的参数生成)
  • description - 要在参数help之前显示的文本(默认值:none)
  • epilog - 参数help(默认:none)之后显示的文本
  • parents - ArgumentParser对象的列表,其中也应该包含参数
  • formatter_class - 用于自定义帮助输出的类
  • prefix_chars - 前缀可选参数的字符集(默认值:' - ')
  • fromfile_prefix_chars - 应该从前缀文件中读取附加参数的一组字符(默认值:None)
  • argument_default - 参数的全局默认值(默认值:None)
  • conflict_handler - 解决冲突选项的策略(通常是不必要的)
  • add_help - 向解析器添加-h/——help选项(默认值:True)
  • allow_abbrev - 允许长选项被缩写,如果缩写是明确的。(默认值是真实的)

修改版本3.5:添加allow_abbrev参数。下面的部分将描述如何使用这些方法。

prog

默认情况下,ArgumentParser对象使用sys。以确定如何在帮助消息中显示程序的名称。这个缺省值几乎总是可取的,因为它将使帮助消息与在命令行上调用程序的方式匹配。例如,考虑一个名为myprogram.py的文件,其代码如下:

代码语言:javascript
复制
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', help='foo help')
args = parser.parse_args()

该程序的帮助将显示myprogram.py作为程序名(无论程序是从哪里调用的):

代码语言:javascript
复制
$ python myprogram.py --help
usage: myprogram.py [-h] [--foo FOO]

optional arguments:
 -h, --help  show this help message and exit
 --foo FOO   foo help
$ cd ..
$ python subdir/myprogram.py --help
usage: myprogram.py [-h] [--foo FOO]

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

要更改此默认行为,可以使用prog= argument向ArgumentParser提供另一个值:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser(prog='myprogram')
>>> parser.print_help()
usage: myprogram [-h]

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

注意,程序名是否由sys决定。可以使用%(prog)格式说明符帮助消息。

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser(prog='myprogram')
>>> parser.add_argument('--foo', help='foo of the %(prog)s program')
>>> parser.print_help()
usage: myprogram [-h] [--foo FOO]

optional arguments:
 -h, --help  show this help message and exit
 --foo FOO   foo of the myprogram program

usage

默认情况下,ArgumentParser从它包含的参数中计算使用消息:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo', nargs='?', help='foo help')
>>> parser.add_argument('bar', nargs='+', help='bar help')
>>> parser.print_help()
usage: PROG [-h] [--foo [FOO]] bar [bar ...]

positional arguments:
 bar          bar help

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

可以使用usage= keyword参数重写默认消息:

代码语言:javascript
复制
>>> 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()
usage: PROG [options]

positional arguments:
 bar          bar help

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

可以使用%(prog)s格式说明符在您的使用消息中填充程序名称。

描述

对ArgumentParser构造函数的大多数调用将使用description= keyword参数。这个参数简要描述了程序的功能及其工作原理。在帮助消息中,描述显示在命令行用法字符串和各种参数的帮助消息之间:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser(description='A foo that bars')
>>> parser.print_help()
usage: argparse.py [-h]

A foo that bars

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

默认情况下,描述将行包装,以便适合给定的空间。要更改此行为,请参阅formatter_class参数。

epilog

有些程序喜欢在参数描述之后显示程序的附加描述。这样的文本可以使用epilog= argument指定ArgumentParser:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser(
...     description='A foo that bars',
...     epilog="And that's how you'd foo a bar")
>>> parser.print_help()
usage: argparse.py [-h]

A foo that bars

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

And that's how you'd foo a bar

与description参数一样,默认情况下epilog= text是行包装的,但是可以使用formatter_class参数到ArgumentParser调整此行为。

parents

有时,几个解析器共享一组公共参数。与其重复这些参数的定义,不如使用一个包含所有共享参数并传递给parent = argument到ArgumentParser的单一解析器。parent =参数获取一个ArgumentParser对象列表,从其中收集所有的位置操作和可选操作,并将这些操作添加到正在构造的ArgumentParser对象中:

代码语言:javascript
复制
>>> parent_parser = argparse.ArgumentParser(add_help=False)
>>> parent_parser.add_argument('--parent', type=int)

>>> foo_parser = argparse.ArgumentParser(parents=[parent_parser])
>>> foo_parser.add_argument('foo')
>>> foo_parser.parse_args(['--parent', '2', 'XXX'])
Namespace(foo='XXX', parent=2)

>>> bar_parser = argparse.ArgumentParser(parents=[parent_parser])
>>> bar_parser.add_argument('--bar')
>>> bar_parser.parse_args(['--bar', 'YYY'])
Namespace(bar='YYY', parent=None)

注意,大多数父解析器将指定add_help=False。否则,ArgumentParser将看到两个-h/——help选项(一个在父类中,一个在子类中),并引发一个错误。

Note

在通过parent =传递解析器之前,必须完全初始化它们。如果在子解析器之后更改父解析器,这些更改将不会反映在子解析器中。

formatter_class

ArgumentParser对象允许通过指定另一个格式化类来定制帮助格式化。目前有四类:

  • class argparse.RawDescriptionHelpFormatter
  • class argparse.RawTextHelpFormatter
  • class argparse.ArgumentDefaultsHelpFormatter
  • class argparse.MetavarTypeHelpFormatter

RawDescriptionHelpFormatter和RawTextHelpFormatter对文本描述的显示方式提供了更多的控制。默认情况下,ArgumentParser对象将描述和epilog文本行包装在命令行帮助消息中:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser(
...     prog='PROG',
...     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.print_help()
usage: PROG [-h]

this description was indented weird but that is okay

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

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

将RawDescriptionHelpFormatter传递为formatter_class=表示描述和epilog已经正确格式化,不应该换行:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser(
...     prog='PROG',
...     formatter_class=argparse.RawDescriptionHelpFormatter,
...     description=textwrap.dedent('''\
...         Please do not mess up this text!
...         --------------------------------
...             I have indented it
...             exactly the way
...             I want it
...         '''))
>>> parser.print_help()
usage: PROG [-h]

Please do not mess up this text!
--------------------------------
   I have indented it
   exactly the way
   I want it

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

RawTextHelpFormatter为各种帮助文本(包括参数描述)维护空白。然而,多行新行被替换为一行。如果希望保留多个空白行,请在换行之间添加空格。ArgumentDefaultsHelpFormatter自动向每个参数帮助消息添加关于默认值的信息:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser(
...     prog='PROG',
...     formatter_class=argparse.ArgumentDefaultsHelpFormatter)
>>> parser.add_argument('--foo', type=int, default=42, help='FOO!')
>>> parser.add_argument('bar', nargs='*', default=[1, 2, 3], help='BAR!')
>>> parser.print_help()
usage: PROG [-h] [--foo FOO] [bar [bar ...]]

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

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

MetavarTypeHelpFormatter为每个参数使用类型参数的名称作为其值的显示名称(而不是像常规格式化程序那样使用dest):

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser(
...     prog='PROG',
...     formatter_class=argparse.MetavarTypeHelpFormatter)
>>> parser.add_argument('--foo', type=int)
>>> parser.add_argument('bar', type=float)
>>> parser.print_help()
usage: PROG [-h] [--foo int] float

positional arguments:
  float

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

prefix_chars

大多数命令行选项将使用-作为前缀,例如-f/——foo。需要支持不同或额外前缀字符的解析器,例如+f或/foo选项,可以使用ArgumentParser构造函数的prefix_chars= argument指定它们:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser(prog='PROG', prefix_chars='-+')
>>> parser.add_argument('+f')
>>> parser.add_argument('++bar')
>>> parser.parse_args('+f X ++bar Y'.split())
Namespace(bar='Y', f='X')

prefix_chars=参数默认为'-'。提供一组不包含-的字符将导致-f/——foo选项被禁用。

fromfile_prefix_chars

有时,例如,当处理一个特别长的参数列表时,将参数列表保存在一个文件中,而不是在命令行中键入参数,可能是有意义的。如果将fromfile_prefix_chars=参数提供给ArgumentParser构造函数,那么以任何指定字符开头的参数都将被视为文件,并由它们包含的参数替换。例如:

代码语言:javascript
复制
>>> with open('args.txt', 'w') as fp:
...     fp.write('-f\nbar')
>>> parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
>>> parser.add_argument('-f')
>>> parser.parse_args(['-f', 'foo', '@args.txt'])
Namespace(f='bar')

默认情况下,从文件中读取的参数必须是每行一个(但也请参阅convert_arg_line_to_args()),并将其视为与在命令行中引用参数的原始文件位于同一位置。在上面的例子中,表达式['-f', 'foo', '@args。txt']被认为等同于表达式['-f', 'foo', '-f', 'bar']。fromfile_prefix_chars=参数默认为None,这意味着参数永远不会被视为文件引用。

argument_default

通常,通过将默认值传递给add_argument()或使用一组特定的名称-值对调用set_defaults()方法来指定参数默认值。然而,有时为参数指定一个解析器范围的默认值可能很有用。这可以通过将argument_default=关键字参数传递给ArgumentParser来实现。例如,为了全局地抑制parse_args()调用上的属性创建,我们提供argument_default= suppress:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)
>>> parser.add_argument('--foo')
>>> parser.add_argument('bar', nargs='?')
>>> parser.parse_args(['--foo', '1', 'BAR'])
Namespace(bar='BAR', foo='1')
>>> parser.parse_args([])
Namespace()

allow_abbrev

通常,当您将参数列表传递给ArgumentParser的parse_args()方法时,它会识别长选项的缩写。这个功能可以通过设置allow_abbrev为False来禁用:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser(prog='PROG', allow_abbrev=False)
>>> parser.add_argument('--foobar', action='store_true')
>>> parser.add_argument('--foonley', action='store_false')
>>> parser.parse_args(['--foon'])
usage: PROG [-h] [--foobar] [--foonley]
PROG: error: unrecognized arguments: --foon

New in version 3.5.

conflict_handler

ArgumentParser对象不允许两个具有相同选项字符串的操作。默认情况下,如果使用已经使用的选项字符串创建参数,ArgumentParser对象会引发异常:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-f', '--foo', help='old foo help')
>>> parser.add_argument('--foo', help='new foo help')
Traceback (most recent call last):
 ..
ArgumentError: argument --foo: conflicting option string(s): --foo

有时(例如,当使用父类时),简单地用相同的选项字符串覆盖任何旧的参数可能是有用的。要获得这种行为,可以将值'resolve'提供给ArgumentParser的conflict t_handler= argument:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser(prog='PROG', conflict_handler='resolve')
>>> parser.add_argument('-f', '--foo', help='old foo help')
>>> parser.add_argument('--foo', help='new foo help')
>>> parser.print_help()
usage: PROG [-h] [-f FOO] [--foo FOO]

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

注意ArgumentParser对象只有在其所有选项字符串都被覆盖时才删除操作。因此,在上面的示例中,旧的-f/——foo操作保留为-f操作,因为只覆盖了——foo选项字符串。

add_help

默认情况下,ArgumentParser对象会添加一个选项,该选项只显示解析器的帮助消息。例如,考虑一个名为myprogram.py的文件,其中包含以下代码:

代码语言:javascript
复制
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', help='foo help')
args = parser.parse_args()

如果在命令行中提供-h或——help,将打印ArgumentParser help:

代码语言:javascript
复制
$ python myprogram.py --help
usage: myprogram.py [-h] [--foo FOO]

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

有时,禁用此帮助选项的添加可能很有用。这可以通过将False作为add_help=参数传递给ArgumentParser来实现:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser(prog='PROG', add_help=False)
>>> parser.add_argument('--foo', help='foo help')
>>> parser.print_help()
usage: PROG [--foo FOO]

optional arguments:
 --foo FOO  foo help

help选项通常是-h/——help。例外情况是,如果指定了前缀_chars=,并且不包含-,在这种情况下-h和——help都不是有效的选项。在本例中,prefix_chars中的第一个字符用于为帮助选项添加前缀:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser(prog='PROG', prefix_chars='+/')
>>> parser.print_help()
usage: PROG [+h]

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

The add_argument() 函数

代码语言:javascript
复制
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 - 一些操作和nargs选择所需的常量。
  • default - 如果参数不在命令行中生成的值。
  • type - 应该将命令行参数转换为的类型。
  • choices - 参数允许值的容器。
  • required - 是否可以省略命令行选项(仅限选项)。
  • help - 一个简短的描述什么论点做。
  • metavar - 使用消息中参数的名称。
  • dest - 要添加到parse_args()返回的对象中的属性的名称。

下面的部分将描述如何使用这些方法。

name or flags

add_argument()方法必须知道是否需要一个可选参数,比如-f或——foo,或者一个位置参数,比如文件名列表。因此,传递给add_argument()的第一个参数必须是一系列标志,或者是一个简单的参数名。例如,可以创建一个可选参数,如下所示:

代码语言:javascript
复制
>>> parser.add_argument('-f', '--foo')

而位置参数可以创建如下:

代码语言:javascript
复制
>>> parser.add_argument('bar')

当调用parse_args()时,可选参数将由-前缀标识,其余参数将假定为位置参数:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-f', '--foo')
>>> parser.add_argument('bar')
>>> parser.parse_args(['BAR'])
Namespace(bar='BAR', foo=None)
>>> parser.parse_args(['BAR', '--foo', 'FOO'])
Namespace(bar='BAR', foo='FOO')
>>> parser.parse_args(['--foo', 'FOO'])
usage: PROG [-h] [-f FOO] bar
PROG: error: the following arguments are required: bar

action

ArgumentParser对象将命令行参数与操作关联起来。这些操作可以对与之关联的命令行参数执行任何操作,尽管大多数操作只是向parse_args()返回的对象添加一个属性。action关键字参数指定应该如何处理命令行参数。所提供的操作如下:

  • 'store' - 它只存储参数的值。这是默认操作。例如: >>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo') >>> parser.parse_args('--foo 1'.split()) Namespace(foo='1')
  • 'store_const' - 它存储由const关键字参数指定的值。“store_const”操作通常与指定某种标志的可选参数一起使用。例如: >>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', action='store_const', const=42) >>> parser.parse_args(['--foo']) Namespace(foo=42)
  • 'store_true' and 'store_false' - 这些是'store_const'的特殊情况,分别用于存储值True和False。此外,它们分别创建False和True的默认值。例如: >>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', action='store_true') >>> parser.add_argument('--bar', action='store_false') >>> parser.add_argument('--baz', action='store_false') >>> parser.parse_args('--foo --bar'.split()) Namespace(foo=True, bar=False, baz=True)
  • 'append' - 它存储一个列表,并将每个参数值附加到列表中。这对于允许多次指定某个选项非常有用。使用示例: >>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', action='append') >>> parser.parse_args('--foo 1 --foo 2'.split()) Namespace(foo=['1', '2'])
  • 'append_const' - 它存储一个列表,并将const关键字参数指定的值附加到列表中。(注意const关键字参数默认为None。)当多个参数需要将常量存储到同一个列表中时,“append_const”操作通常非常有用。例如: >>> 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) >>> parser.parse_args('--str --int'.split()) Namespace(types=[<class 'str'>, <class 'int'>])
  • 'count' - 这将计算关键字参数出现的次数。例如,这对于增加冗长程度很有用: >>> parser = argparse.ArgumentParser() >>> parser.add_argument('--verbose', '-v', action='count') >>> parser.parse_args(['-vvv']) Namespace(verbose=3)
  • 'help' - 这将为当前解析器中的所有选项打印完整的帮助消息,然后退出。默认情况下,帮助操作会自动添加到解析器中。有关如何创建输出的详细信息,请参见ArgumentParser。
  • 'version' - 这需要在add_argument()调用中使用version= keyword参数,并在调用时打印版本信息并退出: >>> 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

还可以通过传递实现相同接口的action子类或其他对象来指定任意操作。推荐的方法是扩展Action,覆盖_call__方法和可选的_init__方法。

自定义操作的一个例子:

代码语言:javascript
复制
>>> class FooAction(argparse.Action):
...     def __init__(self, option_strings, dest, nargs=None, **kwargs):
...         if nargs is not None:
...             raise ValueError("nargs not allowed")
...         super(FooAction, self).__init__(option_strings, dest, **kwargs)
...     def __call__(self, parser, namespace, values, option_string=None):
...         print('%r %r %r' % (namespace, values, option_string))
...         setattr(namespace, self.dest, values)
...
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action=FooAction)
>>> parser.add_argument('bar', action=FooAction)
>>> args = parser.parse_args('1 --foo 2'.split())
Namespace(bar=None, foo=None) '1' None
Namespace(bar='1', foo=None) '2' '--foo'
>>> args
Namespace(bar='1', foo='2')

nargs

ArgumentParser对象通常将一个命令行参数与一个要执行的操作关联起来。nargs关键字参数将不同数量的命令行参数与一个操作关联起来。支持的值是:

  • N (an integer). 命令行中的N个参数将被收集到一个列表中。例如: >>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', nargs=2) >>> parser.add_argument('bar', nargs=1) >>> parser.parse_args('c --foo a b'.split()) Namespace(bar=['c'], foo=['a', 'b']) 注意,nargs=1生成一个包含一项的列表。这与默认值不同,默认值中项目是由自己生成的。
  • '?'. 如果可能,一个参数将从命令行中使用,并作为单个项目生成。如果不存在命令行参数,则会生成默认值。注意,对于可选参数,还有另外一种情况——出现了选项字符串,但后面没有命令行参数。在本例中,将生成来自const的值。一些例子可以说明这一点: >>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', nargs='?', const='c', default='d') >>> parser.add_argument('bar', nargs='?', default='d') >>> parser.parse_args(['XX', '--foo', 'YY']) Namespace(bar='XX', foo='YY') >>> parser.parse_args(['XX', '--foo']) Namespace(bar='XX', foo='c') >>> parser.parse_args([]) Namespace(bar='d', foo='d') nargs='最常见的用法之一是什么?是允许可选的输入和输出文件: >>> 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) >>> parser.parse_args(['input.txt', 'output.txt']) Namespace(infile=<_io.TextIOWrapper name='input.txt' encoding='UTF-8'>, outfile=<_io.TextIOWrapper name='output.txt' encoding='UTF-8'>) >>> parser.parse_args([]) Namespace(infile=<_io.TextIOWrapper name='<stdin>' encoding='UTF-8'>, outfile=<_io.TextIOWrapper name='<stdout>' encoding='UTF-8'>)
  • '*'. 所有当前的命令行参数都被收集到一个列表中。注意,使用多个nargs='*'的位置参数通常没有多大意义,但是使用nargs='*'的多个可选参数是可能的。例如: >>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', nargs='*') >>> parser.add_argument('--bar', nargs='*') >>> parser.add_argument('baz', nargs='*') >>> parser.parse_args('a b --foo x y --bar 1 2'.split()) Namespace(bar=['1', '2'], baz=['a', 'b'], foo=['x', 'y'])
  • '+'. Just like '*',所有当前的命令行arg都被收集到一个列表中。此外,如果没有至少一个命令行参数,将生成错误消息。例如: >>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('foo', nargs='+') >>> parser.parse_args(['a', 'b']) Namespace(foo=['a', 'b']) >>> parser.parse_args([]) usage: PROG [-h] foo [foo ...] PROG: error: the following arguments are required: foo
  • argparse.REMAINDER. 所有剩余的命令行参数都被收集到一个列表中。这对于调度到其他命令行实用程序的命令行实用程序通常很有用: >>> 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')

如果没有提供nargs关键字参数,则使用的参数数量由操作决定。通常,这意味着将使用一个命令行参数,并生成一个项目(而不是列表)。

const

add_argument()的const参数用于保存常量,这些常量不是从命令行读取的,而是用于各种ArgumentParser操作。它最常见的两个用途是:

  • 当使用action='store_const'或action='append_const'调用add_argument()时。这些操作将const值添加到parse_args()返回的对象的一个属性中。有关示例,请参见操作描述。
  • 当使用选项字符串(如-f或——foo)和nargs='?'调用add_argument()时。这将创建一个可选参数,后面可以跟着零个或一个命令行参数。在解析命令行时,如果遇到选项字符串后面没有命令行参数,那么将使用const的值。有关示例,请参见nargs描述。

对于“store_const”和“append_const”操作,必须给出const关键字参数。对于其他操作,默认为None。

default

所有可选参数和一些位置参数都可以在命令行中省略。add_argument()的默认关键字参数的值默认为None,它指定如果命令行参数不存在,应该使用什么值。对于可选参数,在命令行不存在选项字符串时使用默认值:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default=42)
>>> parser.parse_args(['--foo', '2'])
Namespace(foo='2')
>>> parser.parse_args([])
Namespace(foo=42)

如果默认值是字符串,则解析器将解析该值,就像解析命令行参数一样。特别是,在设置名称空间返回值的属性之前,如果提供了类型转换参数,解析器将应用任何类型转换参数。否则,解析器将使用如下值:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--length', default='10', type=int)
>>> parser.add_argument('--width', default=10.5, type=int)
>>> parser.parse_args()
Namespace(length=10, width=10.5)

对于nargs等于?的位置参数?或者*,当没有命令行参数时使用默认值:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('foo', nargs='?', default=42)
>>> parser.parse_args(['a'])
Namespace(foo='a')
>>> parser.parse_args([])
Namespace(foo=42)

提供默认= argparse。如果命令行参数不存在,则不会添加任何属性:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default=argparse.SUPPRESS)
>>> parser.parse_args([])
Namespace()
>>> parser.parse_args(['--foo', '1'])
Namespace(foo='1')

type

默认情况下,ArgumentParser对象以简单字符串的形式读取命令行参数。然而,命令行字符串通常应该被解释为另一种类型,比如float或int. add_argument()的type关键字参数允许执行任何必要的类型检查和类型转换。常见的内置类型和函数可以直接用作类型参数的值:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('foo', type=int)
>>> parser.add_argument('bar', type=open)
>>> parser.parse_args('2 temp.txt'.split())
Namespace(bar=<_io.TextIOWrapper name='temp.txt' encoding='UTF-8'>, foo=2)

有关类型参数何时应用于默认参数的信息,请参阅default关键字参数一节。为了方便使用各种类型的文件,argparse模块提供了工厂文件类型,它接受open()函数的mode=、bufsize=、encoding=和errors=参数。例如,FileType('w')可以用来创建一个可写文件:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('bar', type=argparse.FileType('w'))
>>> parser.parse_args(['out.txt'])
Namespace(bar=<_io.TextIOWrapper name='out.txt' encoding='UTF-8'>)

type=可以接受任何接受单个字符串参数并返回转换值的可调用值:

代码语言:javascript
复制
>>> 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)
>>> parser.parse_args(['9'])
Namespace(foo=9)
>>> parser.parse_args(['7'])
usage: PROG [-h] foo
PROG: error: argument foo: '7' is not a perfect square

对于类型检查器来说,options关键字参数可能更方便,因为它只检查一系列值:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('foo', type=int, choices=range(5, 10))
>>> parser.parse_args(['7'])
Namespace(foo=7)
>>> parser.parse_args(['11'])
usage: PROG [-h] {5,6,7,8,9}
PROG: error: argument foo: invalid choice: 11 (choose from 5, 6, 7, 8, 9)

choices

应该从一组受限制的值中选择一些命令行参数。可以通过将容器对象作为choice关键字参数传递给add_argument()来处理这些问题。当解析命令行时,将检查参数值,如果参数不是可接受的值之一,将显示错误消息:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser(prog='game.py')
>>> parser.add_argument('move', choices=['rock', 'paper', 'scissors'])
>>> parser.parse_args(['rock'])
Namespace(move='rock')
>>> parser.parse_args(['fire'])
usage: game.py [-h] {rock,paper,scissors}
game.py: error: argument move: invalid choice: 'fire' (choose from 'rock',
'paper', 'scissors')

注意,在执行任何类型转换之后,都会检查选项容器中的包含内容,因此选项容器中的对象的类型应该与指定的类型匹配:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser(prog='doors.py')
>>> parser.add_argument('door', type=int, choices=range(1, 4))
>>> print(parser.parse_args(['3']))
Namespace(door=3)
>>> parser.parse_args(['4'])
usage: doors.py [-h] {1,2,3}
doors.py: error: argument door: invalid choice: 4 (choose from 1, 2, 3)

任何支持in操作符的对象都可以作为选择值传递,因此dict对象、set对象、定制容器等都是受支持的。

required

通常,argparse模块假设-f和-bar等标志表示可选参数,这些参数在命令行中总是可以省略。要使选项成为必需的,可以为required= keyword参数指定True,然后将其指定为add_argument():

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', required=True)
>>> parser.parse_args(['--foo', 'BAR'])
Namespace(foo='BAR')
>>> parser.parse_args([])
usage: argparse.py [-h] [--foo FOO]
argparse.py: error: option --foo is required

如示例所示,如果一个选项被标记为required,那么如果该选项不在命令行中,parse_args()将报告一个错误。必需选项通常被认为是不好的形式,因为用户希望选项是可选的,因此应该尽可能避免它们。

help

帮助值是一个字符串,包含参数的简短描述。当用户请求帮助(通常在命令行使用-h或——help)时,这些帮助描述将与每个参数一起显示:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser(prog='frobble')
>>> parser.add_argument('--foo', action='store_true',
...                     help='foo the bars before frobbling')
>>> parser.add_argument('bar', nargs='+',
...                     help='one of the bars to be frobbled')
>>> parser.parse_args(['-h'])
usage: frobble [-h] [--foo] bar [bar ...]

positional arguments:
 bar     one of the bars to be frobbled

optional arguments:
 -h, --help  show this help message and exit
 --foo   foo the bars before frobbling

帮助字符串可以包含各种格式说明符,以避免重复程序名或参数默认值等内容。可用的说明符包括程序名、%(prog)s和add_argument()的大多数关键字参数,例如%(默认值)s、%(类型)s等:

代码语言:javascript
复制
>>> 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

由于帮助字符串支持%-格式化,如果希望帮助字符串中出现文字%,则必须将其转义为%%。通过将帮助值设置为argparse. suppress, argparse支持对某些选项禁用帮助条目:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser(prog='frobble')
>>> parser.add_argument('--foo', help=argparse.SUPPRESS)
>>> parser.print_help()
usage: frobble [-h]

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

metavar

当ArgumentParser生成帮助消息时,它需要某种方法来引用每个期望的参数。默认情况下,ArgumentParser对象使用dest值作为每个对象的“名称”。默认情况下,对于位置参数操作,dest值直接使用,对于可选参数操作,dest值大写。因此,一个位置参数dest='bar'将被称为bar。一个可选参数——foo,后面应该跟着一个命令行参数,这将被称为foo。一个例子:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> parser.add_argument('bar')
>>> parser.parse_args('X --foo Y'.split())
Namespace(bar='X', foo='Y')
>>> parser.print_help()
usage:  [-h] [--foo FOO] bar

positional arguments:
 bar

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

可使用metavar指定替代名称:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', metavar='YYY')
>>> parser.add_argument('bar', metavar='XXX')
>>> parser.parse_args('X --foo Y'.split())
Namespace(bar='X', foo='Y')
>>> parser.print_help()
usage:  [-h] [--foo YYY] XXX

positional arguments:
 XXX

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

注意metavar只更改显示的名称——parse_args()对象上的属性名称仍然由dest值决定。不同的nargs值可能会导致metavar被多次使用。为metavar提供一个元组为每个参数指定一个不同的显示:

代码语言:javascript
复制
>>> 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

dest

大多数ArgumentParser动作都会添加一些值作为parse_args()返回的对象的属性。此属性的名称由add_argument()的dest关键字参数决定。对于位置参数操作,dest通常作为add_argument()的第一个参数提供:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('bar')
>>> parser.parse_args(['XXX'])
Namespace(bar='XXX')

对于可选参数操作,dest的值通常从选项字符串推断。ArgumentParser通过获取第一个长选项字符串并去掉初始字符串——string来生成dest的值。如果没有提供长选项字符串,dest将从第一个短选项字符串中提取初始字符。任何内部字符将被转换为_字符,以确保字符串是一个有效的属性名。下面的例子说明了这种行为:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('-f', '--foo-bar', '--foo')
>>> parser.add_argument('-x', '-y')
>>> parser.parse_args('-f 1 -x 2'.split())
Namespace(foo_bar='1', x='2')
>>> parser.parse_args('--foo 1 -y 2'.split())
Namespace(foo_bar='1', x='2')

dest允许提供自定义属性名:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', dest='bar')
>>> parser.parse_args('--foo XXX'.split())
Namespace(bar='XXX')

Action类

Action类实现Action API,一个可调用的API返回一个可调用的API,该API处理命令行中的参数。任何遵循此API的对象都可以作为操作参数传递给add_argument()。

代码语言:javascript
复制
class argparse.Action(option_strings, dest, nargs=None, const=None, default=None, type=None, choices=None, required=False, help=None, metavar=None)

ArgumentParser使用Action对象来表示从命令行中的一个或多个字符串解析单个参数所需的信息。Action类必须接受两个位置参数和传递给ArgumentParser.add_argument()的关键字参数(除了Action本身)。Action实例(或任何可调用Action参数的返回值)应该定义属性“dest”、“option_string”、“default”、“type”、“required”、“help”等。确保定义这些属性的最简单方法是调用action . _init__。Action实例应该是可调用的,因此子类必须覆盖_call__方法,该方法应该接受四个参数:

  • parser - 包含此操作的ArgumentParser对象。
  • namespace - 将由parse_args()返回的名称空间对象。大多数操作使用setattr()向该对象添加属性。
  • values - 关联的命令行参数,以及应用的任何类型转换。类型转换由Type关键字参数指定为add_argument()。
  • option_string - 用于调用此操作的选项字符串。option_string参数是可选的,如果操作与位置参数关联,则该参数将不存在。

方法可以执行任意操作,但通常会基于dest和值在名称空间上设置属性。

The parse_args() method

代码语言:javascript
复制
ArgumentParser.parse_args(args=None, namespace=None)

将参数字符串转换为对象,并将它们指定为名称空间的属性。返回填充的名称空间。之前对add_argument()的调用确定了创建什么对象以及如何分配对象。有关详细信息,请参阅add_argument()文档。

  • args - 要解析的字符串列表。默认值取自sys.argv。
  • namespace - 获取属性的对象。默认值是一个新的空名称空间对象。

Option value syntax

parse_args()方法支持几种指定选项值的方法(如果接受一种方法)。在最简单的情况下,该选项及其值作为两个单独的参数传递:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-x')
>>> parser.add_argument('--foo')
>>> parser.parse_args(['-x', 'X'])
Namespace(foo=None, x='X')
>>> parser.parse_args(['--foo', 'FOO'])
Namespace(foo='FOO', x=None)

对于长选项(名称大于单个字符的选项),也可以将选项和值作为单个命令行参数传递,使用=分隔它们:

代码语言:javascript
复制
>>> parser.parse_args(['--foo=FOO'])
Namespace(foo='FOO', x=None)

对于较短的选项(选项只有一个字符长),可以将该选项及其值连接起来:

代码语言:javascript
复制
>>> parser.parse_args(['-xX'])
Namespace(foo=None, x='X')

几个短选项可以连接在一起,只使用一个前缀,只要只有最后一个选项(或没有一个选项)需要一个值:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-x', action='store_true')
>>> parser.add_argument('-y', action='store_true')
>>> parser.add_argument('-z')
>>> parser.parse_args(['-xyzZ'])
Namespace(x=True, y=True, z='Z')

Invalid arguments

在解析命令行时,parse_args()检查各种错误,包括不明确的选项、无效类型、无效选项、错误的位置参数数量等。当它遇到这样的错误时,它会退出并打印错误以及使用信息:

代码语言:javascript
复制
>>> 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

Arguments containing -

parse_args()方法尝试在用户明显犯了错误时给出错误,但是有些情况本质上是模棱两可的。例如,命令行参数-1可以是指定选项的尝试,也可以是提供位置参数的尝试。parse_args()方法在这里很谨慎:位置参数可能只以-如果它们看起来像负数,并且解析器中没有看起来像负数的选项,那么:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-x')
>>> parser.add_argument('foo', nargs='?')

>>> # no negative number options, so -1 is a positional argument
>>> parser.parse_args(['-x', '-1'])
Namespace(foo=None, x='-1')

>>> # no negative number options, so -1 and -5 are positional arguments
>>> parser.parse_args(['-x', '-1', '-5'])
Namespace(foo='-5', x='-1')

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-1', dest='one')
>>> parser.add_argument('foo', nargs='?')

>>> # negative number options present, so -1 is an option
>>> parser.parse_args(['-1', 'X'])
Namespace(foo=None, one='X')

>>> # negative number options present, so -2 is an option
>>> parser.parse_args(['-2'])
usage: PROG [-h] [-1 ONE] [foo]
PROG: error: no such option: -2

>>> # negative number options present, so both -1s are options
>>> parser.parse_args(['-1', '-1'])
usage: PROG [-h] [-1 ONE] [foo]
PROG: error: argument -1: expected one argument

如果你的位置参数必须以-开头,而且看起来不像负数,你可以插入伪参数'- ',它告诉parse_args()后面的所有东西都是位置参数:

代码语言:javascript
复制
>>> parser.parse_args(['--', '-f'])
Namespace(foo='-f', one=None)

Argument缩减

默认情况下,parse_args()方法允许将长选项缩写为前缀,如果缩写没有歧义(前缀匹配唯一选项):

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-bacon')
>>> parser.add_argument('-badger')
>>> parser.parse_args('-bac MMM'.split())
Namespace(bacon='MMM', badger=None)
>>> parser.parse_args('-bad WOOD'.split())
Namespace(bacon=None, badger='WOOD')
>>> parser.parse_args('-ba BA'.split())
usage: PROG [-h] [-bacon BACON] [-badger BADGER]
PROG: error: ambiguous option: -ba could match -badger, -bacon

对于可能产生多个选项的参数会产生错误。可以通过将allow_abbrev设置为False禁用此特性。

Beyond sys.argv

有时候,使用ArgumentParser解析sys.argv之外的参数可能很有用。这可以通过将字符串列表传递给parse_args()来实现。这对于在交互提示符下进行测试非常有用:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument(
...     'integers', metavar='int', type=int, choices=range(10),
...     nargs='+', help='an integer in the range 0..9')
>>> parser.add_argument(
...     '--sum', dest='accumulate', action='store_const', const=sum,
...     default=max, help='sum the integers (default: find the max)')
>>> parser.parse_args(['1', '2', '3', '4'])
Namespace(accumulate=<built-in function max>, integers=[1, 2, 3, 4])
>>> parser.parse_args(['1', '2', '3', '4', '--sum'])
Namespace(accumulate=<built-in function sum>, integers=[1, 2, 3, 4])

The Namespace object

代码语言:javascript
复制
class argparse.Namespace

parse_args()默认情况下使用Simple类创建一个包含属性的对象并返回它。这个类非常简单,只是一个带有可读字符串表示的对象子类。如果您希望属性具有类似于词典的视图,可以使用标准Python习语vars():

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> args = parser.parse_args(['--foo', 'BAR'])
>>> vars(args)
{'foo': 'BAR'}

让ArgumentParser将属性分配给一个已经存在的对象,而不是一个新的名称空间对象,这可能也很有用。这可以通过指定namespace= keyword参数来实现:

代码语言:javascript
复制
>>> class C:
...     pass
...
>>> c = C()
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> parser.parse_args(args=['--foo', 'BAR'], namespace=c)
>>> c.foo
'BAR'

Other utilities

Sub-commands

代码语言:javascript
复制
ArgumentParser.add_subparsers([title][, description][, prog][, parser_class][, action][, option_string][, dest][, required][, help][, metavar])

许多程序将其功能分解为许多子命令,例如,svn程序可以调用svn checkout、svn update和svn commit等子命令。当一个程序执行几个不同的函数,而这些函数又需要不同类型的命令行参数时,以这种方式分割功能可能是一个特别好的主意。ArgumentParser支持使用add_subparsers()方法创建这样的子命令。add_subparsers()方法通常不带参数调用,并返回一个特殊的操作对象。这个对象只有一个方法add_parser(),它接受命令名和任何ArgumentParser构造函数参数,并返回一个可以像往常一样修改的ArgumentParser对象。

对参数的描述:

  • title - 帮助输出中子解析器组的标题;默认情况下,如果提供描述,则使用“子命令”,否则使用title作为位置参数。
  • description - 帮助输出中的子解析器组的描述,默认情况下为None。
  • prog - 使用子命令帮助将显示的使用信息,默认情况下程序的名称和子解析器参数之前的任何位置参数。
  • parser_class - 用于创建子解析器实例的类,默认情况下是当前解析器的类(例如ArgumentParser)。
  • action - 当在命令行中遇到这个参数时要采取的基本操作类型。
  • dest - 将存储子命令名的属性的名称;默认情况下,不存储任何值。
  • required - 是否必须提供子命令,默认情况下为False。
  • help - 帮助输出中的子解析器组的帮助,默认为None。
  • metavar - 在帮助中显示可用子命令的字符串;默认情况下,它是None,并以{cmd1, cmd2, ..}的形式显示子命令。

一些使用例子:

代码语言:javascript
复制
>>> # create the top-level parser
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo', action='store_true', help='foo help')
>>> subparsers = parser.add_subparsers(help='sub-command help')
>>>
>>> # create the parser for the "a" command
>>> parser_a = subparsers.add_parser('a', help='a help')
>>> parser_a.add_argument('bar', type=int, help='bar help')
>>>
>>> # create the parser for the "b" command
>>> parser_b = subparsers.add_parser('b', help='b help')
>>> parser_b.add_argument('--baz', choices='XYZ', help='baz help')
>>>
>>> # parse some argument lists
>>> parser.parse_args(['a', '12'])
Namespace(bar=12, foo=False)
>>> parser.parse_args(['--foo', 'b', '--baz', 'Z'])
Namespace(baz='Z', foo=True)

注意,parse_args()返回的对象只包含由命令行选择的主解析器和子解析器的属性(而不包含任何其他子解析器)。所以在上面的例子中,当a命令被指定时,只有foo和bar属性存在,当b命令被指定时,只有foo和baz属性存在。类似地,当从子解析器请求帮助消息时,只会打印该特定解析器的帮助。帮助消息将不包括父解析器或兄弟解析器消息。(但是,可以通过如上所述向add_parser()提供help=参数来为每个子解析器命令提供帮助消息。)

代码语言:javascript
复制
>>> parser.parse_args(['--help'])
usage: PROG [-h] [--foo] {a,b} ...

positional arguments:
  {a,b}   sub-command help
    a     a help
    b     b help

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

>>> parser.parse_args(['a', '--help'])
usage: PROG a [-h] bar

positional arguments:
  bar     bar help

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

>>> parser.parse_args(['b', '--help'])
usage: PROG b [-h] [--baz {X,Y,Z}]

optional arguments:
  -h, --help     show this help message and exit
  --baz {X,Y,Z}  baz help

add_subparsers()方法还支持title和description关键字参数。当其中之一出现时,子解析器的命令将出现在帮助输出中的它们自己的组中。例如:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser()
>>> subparsers = parser.add_subparsers(title='subcommands',
...                                    description='valid subcommands',
...                                    help='additional help')
>>> subparsers.add_parser('foo')
>>> subparsers.add_parser('bar')
>>> parser.parse_args(['-h'])
usage:  [-h] {foo,bar} ...

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

subcommands:
  valid subcommands

  {foo,bar}   additional help

此外,add_parser支持一个附加的别名参数,该参数允许多个字符串引用同一个子解析器。这个例子,像svn一样,别名co作为结帐的缩写:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser()
>>> subparsers = parser.add_subparsers()
>>> checkout = subparsers.add_parser('checkout', aliases=['co'])
>>> checkout.add_argument('foo')
>>> parser.parse_args(['co', 'bar'])
Namespace(foo='bar')

处理子命令的一种特别有效的方法是将add_subparsers()方法的使用与对set_defaults()的调用结合起来,这样每个子解析器都知道应该执行哪个Python函数。例如:

代码语言:javascript
复制
>>> # sub-command functions
>>> def foo(args):
...     print(args.x * args.y)
...
>>> def bar(args):
...     print('((%s))' % args.z)
...
>>> # create the top-level parser
>>> parser = argparse.ArgumentParser()
>>> subparsers = parser.add_subparsers()
>>>
>>> # create the parser for the "foo" command
>>> parser_foo = subparsers.add_parser('foo')
>>> parser_foo.add_argument('-x', type=int, default=1)
>>> parser_foo.add_argument('y', type=float)
>>> parser_foo.set_defaults(func=foo)
>>>
>>> # create the parser for the "bar" command
>>> parser_bar = subparsers.add_parser('bar')
>>> parser_bar.add_argument('z')
>>> parser_bar.set_defaults(func=bar)
>>>
>>> # parse the args and call whatever function was selected
>>> args = parser.parse_args('foo 1 -x 2'.split())
>>> args.func(args)
2.0
>>>
>>> # parse the args and call whatever function was selected
>>> args = parser.parse_args('bar XYZYX'.split())
>>> args.func(args)
((XYZYX))

通过这种方式,您可以让parse_args()在参数解析完成后调用适当的函数。将函数与这样的操作关联通常是处理每个子解析器的不同操作的最简单方法。但是,如果需要检查调用的子解析器的名称,那么add_subparsers()调用的dest关键字参数将起作用:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser()
>>> subparsers = parser.add_subparsers(dest='subparser_name')
>>> subparser1 = subparsers.add_parser('1')
>>> subparser1.add_argument('-x')
>>> subparser2 = subparsers.add_parser('2')
>>> subparser2.add_argument('y')
>>> parser.parse_args(['2', 'frobble'])
Namespace(subparser_name='2', y='frobble')

FileType objects

代码语言:javascript
复制
class argparse.FileType(mode='r', bufsize=-1, encoding=None, errors=None)

FileType工厂创建可以传递给ArgumentParser.add_argument()的类型参数的对象。将FileType对象作为其类型的参数将以文件的形式打开命令行参数,这些文件具有所请求的模式、缓冲区大小、编码和错误处理(有关详细信息,请参阅open()函数):

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--raw', type=argparse.FileType('wb', 0))
>>> parser.add_argument('out', type=argparse.FileType('w', encoding='UTF-8'))
>>> 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'>)

FileType对象理解伪参数'-',并自动将其转换为sys。stdin用于可读的文件类型对象和sys。可写文件类型对象的标准输出:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('infile', type=argparse.FileType('r'))
>>> parser.parse_args(['-'])
Namespace(infile=<_io.TextIOWrapper name='<stdin>' encoding='UTF-8'>)

Argument groups

代码语言:javascript
复制
ArgumentParser.add_argument_group(title=None, description=None)

默认情况下,ArgumentParser在显示帮助消息时将命令行参数分组为“位置参数”和“可选参数”。当参数的概念分组比默认的更好时,可以使用add_argument_group()方法创建适当的组:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser(prog='PROG', add_help=False)
>>> group = parser.add_argument_group('group')
>>> group.add_argument('--foo', help='foo help')
>>> group.add_argument('bar', help='bar help')
>>> parser.print_help()
usage: PROG [--foo FOO] bar

group:
  bar    bar help
  --foo FOO  foo help

add_argument_group()方法返回一个参数组对象,该对象具有一个add_argument()方法,就像一个常规的ArgumentParser一样。当一个参数被添加到组中时,解析器就像对待一个普通的参数一样对待它,但是会在一个单独的组中显示该参数以获取帮助消息。add_argument_group()方法接受title和description参数,这些参数可用于自定义这个显示:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser(prog='PROG', add_help=False)
>>> group1 = parser.add_argument_group('group1', 'group1 description')
>>> group1.add_argument('foo', help='foo help')
>>> group2 = parser.add_argument_group('group2', 'group2 description')
>>> group2.add_argument('--bar', help='bar help')
>>> parser.print_help()
usage: PROG [--bar BAR] foo

group1:
  group1 description

  foo    foo help

group2:
  group2 description

  --bar BAR  bar help

注意,任何不在用户定义的组中的参数都将回到通常的“位置参数”和“可选参数”部分。

Mutual exclusion

代码语言:javascript
复制
ArgumentParser.add_mutually_exclusive_group(required=False)

创建一个互斥组。argparse将确保互斥组中只有一个参数出现在命令行上:

代码语言:javascript
复制
>>> 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')
>>> parser.parse_args(['--foo'])
Namespace(bar=True, foo=True)
>>> parser.parse_args(['--bar'])
Namespace(bar=False, foo=False)
>>> parser.parse_args(['--foo', '--bar'])
usage: PROG [-h] [--foo | --bar]
PROG: error: argument --bar: not allowed with argument --foo

add_mutually_exclusive_group()方法也接受一个必需的参数,以表明至少需要一个互斥参数:

代码语言:javascript
复制
>>> 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')
>>> parser.parse_args([])
usage: PROG [-h] (--foo | --bar)
PROG: error: one of the arguments --foo --bar is required

注意,当前互斥的参数组不支持add_argument_group()的标题和描述参数。

Parser defaults

代码语言:javascript
复制
ArgumentParser.set_defaults(**kwargs)

大多数时候,parse_args()返回的对象的属性将通过检查命令行参数和参数操作完全确定。set_defaults()允许添加一些额外的属性,这些属性是在不检查命令行的情况下确定的:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('foo', type=int)
>>> parser.set_defaults(bar=42, baz='badger')
>>> parser.parse_args(['736'])
Namespace(bar=42, baz='badger', foo=736)

注意,解析器级别的默认值总是覆盖参数级别的默认值:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default='bar')
>>> parser.set_defaults(foo='spam')
>>> parser.parse_args([])
Namespace(foo='spam')

在使用多个解析器时,解析器级别的缺省值尤其有用。有关此类型的示例,请参见add_subparsers()方法。

代码语言:javascript
复制
ArgumentParser.get_default(dest)

获取名称空间属性的默认值,由add_argument()或set_defaults()设置:

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default='badger')
>>> parser.get_default('foo')
'badger'

Printing help

在大多数典型的应用程序中,parse_args()将负责格式化和打印任何使用或错误消息。然而,有几种格式化方法:

ArgumentParser.print_usage(file=None)

打印一个关于应该如何在命令行上调用ArgumentParser的简短描述。如果文件为空,则sys。stdout。

代码语言:javascript
复制
ArgumentParser.print_help(file=None)

打印一条帮助消息,包括程序使用情况和关于ArgumentParser注册的参数的信息。如果文件为空,则sys.stdout。这些方法也有一些变体,它们只是返回一个字符串,而不是打印它:

ArgumentParser.format_usage()

返回一个字符串,该字符串包含应该如何在命令行上调用ArgumentParser的简短描述。

ArgumentParser.format_help()

返回一个包含帮助消息的字符串,包括程序使用情况和关于ArgumentParser注册的参数的信息。

Partial parsing

代码语言:javascript
复制
ArgumentParser.parse_known_args(args=None, namespace=None)

有时一个脚本可能只解析几个命令行参数,将剩余的参数传递给另一个脚本或程序。在这些情况下,parse_known_args()方法可能很有用。它的工作原理很像parse_args(),只是在出现额外参数时不会产生错误。相反,它返回一个包含填充名称空间和剩余参数字符串列表的两项元组。

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='store_true')
>>> parser.add_argument('bar')
>>> parser.parse_known_args(['--foo', '--badger', 'BAR', 'spam'])
(Namespace(bar='BAR', foo=True), ['--badger', 'spam'])

Warning

前缀匹配规则适用于parse_known_args()。解析器可能会使用一个选项,即使它只是它的一个已知选项的前缀,而不是将它留在剩余的arguments列表中。

Customizing file parsing

代码语言:javascript
复制
ArgumentParser.convert_arg_line_to_args(arg_line)

从文件中读取的参数(请参阅fromfile_prefix_chars关键字参数到ArgumentParser构造函数)每一行读取一个参数。convert_arg_line_to_args()可以被覆盖,以便更好地阅读。这个方法接受一个参数arg_line,它是从参数文件中读取的字符串。它返回从该字符串解析的参数列表。方法按顺序每行从参数文件中读取一次。此方法的一个有用覆盖是将每个空格分隔的单词作为一个参数。下面的例子演示了如何做到这一点:

代码语言:javascript
复制
class MyArgumentParser(argparse.ArgumentParser):
    def convert_arg_line_to_args(self, arg_line):
        return arg_line.split()

Exiting methods

代码语言:javascript
复制
ArgumentParser.exit(status=0, message=None)

此方法终止程序,以指定的状态退出,如果给定,则在此之前打印一条消息。

代码语言:javascript
复制
ArgumentParser.error(message)

此方法将一个使用消息(包括发送给标准错误的消息)打印出来,并使用状态代码2终止程序。

Intermixed parsing

代码语言:javascript
复制
ArgumentParser.parse_intermixed_args(args=None, namespace=None)

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

许多Unix命令允许用户将可选参数与位置参数混合使用。parse_intermixed_args()和parse_known_intermixed_args()方法支持这种解析风格。这些解析器不支持所有argparse特性,如果使用不支持的特性,就会引发异常。特别是子解析器argparse。不支持同时包含选项和位置的剩余组和互斥组。下面的示例显示了parse_known_args()和parse_intermixed_args()之间的区别:前者返回['2','3']作为未解析的参数,而后者将所有的位置信息收集到rest中。

代码语言:javascript
复制
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> parser.add_argument('cmd')
>>> parser.add_argument('rest', nargs='*', type=int)
>>> parser.parse_known_args('doit 1 --foo bar 2 3'.split())
(Namespace(cmd='doit', foo='bar', rest=[1]), ['2', '3'])
>>> parser.parse_intermixed_args('doit 1 --foo bar 2 3'.split())
Namespace(cmd='doit', foo='bar', rest=[1, 2, 3])

parse_known_intermixed_args()返回一个包含填充名称空间和剩余参数字符串列表的两项元组。如果有任何剩余的未解析参数字符串,parse_intermixed_args()将引发错误。

Upgrading optparse code

最初,argparse模块试图保持与optparse的兼容性。但是,optparse很难透明地扩展,特别是需要进行更改来支持新的nargs=说明符和更好的使用消息。当optparse中的大多数内容要么是复制粘贴的,要么是修改过的,那么试图保持向后兼容性似乎就不再可行了。

argparse模块在许多方面改进了标准库optparse模块,包括:

  • 处理位置参数。
  • 支持sub-commands。
  • 允许使用+和/这样的替代选项前缀。
  • 处理零个或多个样式参数和一个或多个样式参数。
  • 生成更多信息的使用消息。
  • 为自定义类型和操作提供更简单的接口。

从optparse到argparse的部分升级路径:

  • 用ArgumentParser.add_argument()调用替换所有的optparser . optionparser .add_option()调用。
  • 用args = parser.parse_args()替换(options, args) = parser.parse_args(),并为位置参数添加额外的ArgumentParser.add_argument()调用。请记住,以前称为options,现在在argparse上下文中称为args。
  • 使用parse_intermixed_args()代替parse_args()来替换optparse.OptionParser.disable_interspersed_args()。
  • 用类型或操作参数替换回调操作和callback_*关键字参数。
  • 用相应的类型对象(例如int、float、complex等)替换类型关键字参数的字符串名称。
  • 取代optparse。具有名称空间和optparse的值。OptionError optparse。OptionValueError ArgumentError。
  • 使用标准Python语法用隐式参数(如%default或%prog)替换字符串,使用字典格式化字符串,即%(default)s和%(prog)s。
  • 用对parser的调用替换OptionParser构造函数版本参数。add_argument('——version', action='version', version='<版本>')。
  • 用ArgumentParser.add_argument()调用替换所有的optparser . optionparser .add_option()调用。
  • 用args = parser.parse_args()替换(options, args) = parser.parse_args(),并为位置参数添加额外的ArgumentParser.add_argument()调用。请记住,以前称为options,现在在argparse上下文中称为args。
  • 使用parse_intermixed_args()代替parse_args()来替换optparse.OptionParser.disable_interspersed_args()。
  • 用类型或操作参数替换回调操作和callback_*关键字参数。
  • 用相应的类型对象(例如int、float、complex等)替换类型关键字参数的字符串名称。
  • 取代optparse。具有名称空间和optparse的值。OptionError optparse。OptionValueError ArgumentError。
  • 使用标准Python语法用隐式参数(如%default或%prog)替换字符串,使用字典格式化字符串,即%(default)s和%(prog)s。
  • 用对parser的调用替换OptionParser构造函数版本参数。add_argument('——version', action='version', version='<版本>')。
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年09月17日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 创建一个解析器
  • 添加参数
  • 解析参数
  • ArgumentParser对象
    • prog
      • usage
        • 描述
          • epilog
            • parents
              • formatter_class
                • prefix_chars
                  • fromfile_prefix_chars
                    • argument_default
                      • allow_abbrev
                        • conflict_handler
                          • add_help
                          • The add_argument() 函数
                            • name or flags
                              • action
                                • nargs
                                  • const
                                    • default
                                      • type
                                        • choices
                                          • required
                                            • help
                                              • metavar
                                                • dest
                                                  • Action类
                                                  • The parse_args() method
                                                    • Option value syntax
                                                      • Invalid arguments
                                                        • Arguments containing -
                                                          • Argument缩减
                                                            • Beyond sys.argv
                                                              • The Namespace object
                                                              • Other utilities
                                                                • Sub-commands
                                                                  • FileType objects
                                                                    • Argument groups
                                                                      • Mutual exclusion
                                                                        • Parser defaults
                                                                          • Printing help
                                                                            • Partial parsing
                                                                              • Customizing file parsing
                                                                                • Exiting methods
                                                                                  • Intermixed parsing
                                                                                  • Upgrading optparse code
                                                                                  相关产品与服务
                                                                                  容器服务
                                                                                  腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                                                                                  领券
                                                                                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档