argparse — 命令行选项、参数和子命令的解析器 — Python 文档

来自菜鸟教程
Python/docs/3.8/library/argparse
跳转至:导航、​搜索

argparse — 命令行选项、参数和子命令的解析器

3.2 版中的新功能。


源代码: :source:`Lib/argparse.py`



教程

此页面包含 API 参考信息。 有关 Python 命令行解析的更温和的介绍,请查看 argparse 教程

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

例子

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

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.py 的文件中,它可以在命令行运行并提供有用的帮助信息:

$ 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)

当使用适当的参数运行时,它会打印命令行整数的总和或最大值:

$ python prog.py 1 2 3 4
4

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

如果传入无效参数,则会报错:

$ python prog.py a b c
usage: prog.py [-h] [--sum] N [N ...]
prog.py: error: argument N: invalid int value: 'a'

以下部分将引导您完成此示例。

创建解析器

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

>>> parser = argparse.ArgumentParser(description='Process some integers.')

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


添加参数

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

>>> 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() 将返回一个具有两个属性的对象,integersaccumulateintegers 属性将是一个或多个整数的列表,accumulate 属性将是 sum() 函数,如果 --sum 是在命令行中指定,如果不是,则在 max() 函数中指定。


解析参数

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

>>> parser.parse_args(['--sum', '7', '-1', '42'])
Namespace(accumulate=<built-in function sum>, integers=[7, -1, 42])

在脚本中,parse_args() 通常不带参数调用,而 ArgumentParser 将自动确定来自 sys.argv 的命令行参数。


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)

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

  • 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

3.5 版更改:添加了 allow_abbrev 参数。

3.8 版更改: 在之前的版本中,allow_abbrev 还禁用了对诸如 -vv 之类的短标志分组以表示 -v -v

以下各节描述了如何使用它们中的每一个。

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

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

该程序的帮助将显示 myprogram.py 作为程序名称(无论从何处调用该程序):

$ 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

要更改此默认行为,可以使用 ArgumentParserprog= 参数提供另一个值:

>>> parser = argparse.ArgumentParser(prog='myprogram')
>>> parser.print_help()
usage: myprogram [-h]

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

请注意,无论是从 sys.argv[0] 还是从 prog= 参数确定的程序名称,都可用于使用 %(prog)s 格式说明符的帮助消息。

>>> 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

用法

默认情况下,ArgumentParser 根据它包含的参数计算用法消息:

>>> 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= 关键字参数覆盖:

>>> 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= 关键字参数。 该参数简要描述了程序的作用和工作方式。 在帮助消息中,描述显示在命令行用法字符串和各种参数的帮助消息之间:

>>> 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 参数。


结语

一些程序喜欢在参数描述之后显示程序的附加描述。 可以使用 ArgumentParserepilog= 参数指定此类文本:

>>> 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= 文本默认为换行,但可以使用 formatter_class 参数调整 ArgumentParser ]。


父母

有时,多个解析器共享一组公共参数。 不是重复这些参数的定义,而是可以使用具有所有共享参数并传递给 parents= 参数到 ArgumentParser 的单个解析器。 parents= 参数采用 ArgumentParser 对象列表,从中收集所有位置和可选操作,并将这些操作添加到正在构造的 ArgumentParser 对象中:

>>> 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 选项(一个在父级中,一个在子级中)并引发错误。

笔记

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


格式化程序类

ArgumentParser 对象允许通过指定替代格式类来自定义帮助格式。 目前,有四个这样的类:

class argparse.RawDescriptionHelpFormatter

class argparse.RawTextHelpFormatter
class argparse.ArgumentDefaultsHelpFormatter
class argparse.MetavarTypeHelpFormatter

RawDescriptionHelpFormatterRawTextHelpFormatter 可以更好地控制文本描述的显示方式。 默认情况下,ArgumentParser 对象对命令行帮助消息中的 descriptionepilog 文本进行换行:

>>> 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= 传递表示 descriptionepilog 已正确格式化,不应换行:

>>> 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 自动将有关默认值的信息添加到每个参数帮助消息中:

>>> 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 使用每个参数的 type 参数的名称作为其值的显示名称(而不是像常规格式化程序那样使用 dest):

>>> 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

前缀字符

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

>>> 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 构造函数,则以任何指定字符开头的参数将被视为文件,并将被它们包含的参数替换。 例如:

>>> 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,这意味着参数永远不会被视为文件引用。


参数_默认值

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

>>> 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

通常,当您将参数列表传递给 ArgumentParserparse_args() 方法时,它 识别长选项的缩写

可以通过将 allow_abbrev 设置为 False 来禁用此功能:

>>> 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

3.5 版中的新功能。


冲突处理程序

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

>>> 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

有时(例如 当使用 parents) 时,用相同的选项字符串简单地覆盖任何旧参数可能很有用。 要获得此行为,可以将值 'resolve' 提供给 ArgumentParserconflict_handler= 参数:

>>> 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 选项字符串被覆盖。


添加帮助

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

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

如果在命令行提供 -h--help,将打印 ArgumentParser 帮助:

$ 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 来实现:

>>> 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

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

>>> parser = argparse.ArgumentParser(prog='PROG', prefix_chars='+/')
>>> parser.print_help()
usage: PROG [+h]

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

add_argument() 方法

ArgumentParser.add_argument(name or flags...[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest])
定义应如何解析单个命令行参数。 每个参数在下面都有更详细的描述,但简而言之,它们是:
  • name 或 flags - 名称或选项字符串列表,例如 foo-f, --foo
  • action - 在命令行遇到此参数时要采取的基本操作类型。
  • nargs - 应该使用的命令行参数的数量。
  • const - 某些 actionnargs 选择所需的常量值。
  • default - 命令行中没有参数时产生的值。
  • type - 命令行参数应转换为的类型。
  • choices - 参数允许值的容器。
  • required - 是否可以省略命令行选项(仅限可选)。
  • help - 对参数作用的简要描述。
  • metavar - 使用消息中参数的名称。
  • dest - 要添加到 parse_args() 返回的对象的属性名称。

以下各节描述了如何使用它们中的每一个。

名称或标志

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

>>> parser.add_argument('-f', '--foo')

虽然可以创建位置参数,例如:

>>> parser.add_argument('bar')

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

>>> 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

行动

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''store_false' - 这些是 'store_const' 的特例,分别用于存储值 TrueFalse。 此外,它们分别创建 FalseTrue 的默认值。 例如:

    >>> 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', default=0)
    >>> parser.parse_args(['-vvv'])
    Namespace(verbose=3)

    请注意,除非明确设置为 0,否则 默认 将为 None

  • 'help' - 这会打印当前解析器中所有选项的完整帮助消息,然后退出。 默认情况下,帮助操作会自动添加到解析器中。 有关如何创建输出的详细信息,请参阅 ArgumentParser

  • '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
  • 'extend' - 这存储一个列表,并将每个参数值扩展到列表。 用法示例:

    >>> parser = argparse.ArgumentParser()
    >>> parser.add_argument("--foo", action="extend", nargs="+", type=str)
    >>> parser.parse_args(["--foo", "f1", "--foo", "f2", "f3", "f4"])
    Namespace(foo=['f1', 'f2', 'f3', 'f4'])

    3.8 版中的新功能。

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

自定义操作的示例:

>>> class FooAction(argparse.Action):
...     def __init__(self, option_strings, dest, nargs=None, **kwargs):
...         if nargs is not None:
...             raise ValueError("nargs not allowed")
...         super().__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(整数)。 来自命令行的 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 生成一个包含一项的列表。 这与默认情况下不同,默认情况下项目是由自己生产的。

  • '?'。 如果可能,将从命令行使用一个参数,并作为单个项目生成。 如果不存在命令行参数,则将生成 default 中的值。 请注意,对于可选参数,还有一种情况 - 选项字符串存在但后面没有命令行参数。 在这种情况下,将产生来自 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'])
  • '+'。 就像 '*' 一样,所有存在的命令行参数都被收集到一个列表中。 此外,如果不存在至少一个命令行参数,则会生成一条错误消息。 例如:

    >>> 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 关键字参数,则消耗的参数数量由 action 决定。 通常这意味着将使用单个命令行参数并生成单个项目(不是列表)。


常量

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

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

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


默认

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

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default=42)
>>> parser.parse_args(['--foo', '2'])
Namespace(foo='2')
>>> parser.parse_args([])
Namespace(foo=42)

如果 default 值是一个字符串,解析器将解析该值,就好像它是一个命令行参数一样。 特别是,解析器在设置 Namespace 返回值的属性之前应用任何 type 转换参数(如果提供)。 否则,解析器按原样使用该值:

>>> 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 等于 ?* 的位置参数,当不存在命令行参数时使用 default 值:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('foo', nargs='?', default=42)
>>> parser.parse_args(['a'])
Namespace(foo='a')
>>> parser.parse_args([])
Namespace(foo=42)

如果命令行参数不存在,则提供 default=argparse.SUPPRESS 会导致不添加任何属性:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default=argparse.SUPPRESS)
>>> parser.parse_args([])
Namespace()
>>> parser.parse_args(['--foo', '1'])
Namespace(foo='1')

类型

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

>>> 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)

有关何时将 type 参数应用于默认参数的信息,请参阅有关 default 关键字参数的部分。

为了方便使用各种类型的文件,argparse 模块提供了工厂 FileType,它采用 mode=bufsize=encoding=errors= 参数open() 函数。 例如,FileType('w') 可用于创建可写文件:

>>> 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= 可以接受任何接受单个字符串参数并返回转换后的值的可调用对象:

>>> 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

choices 关键字参数对于简单检查一系列值的类型检查器可能更方便:

>>> 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 部分。


选择

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

>>> 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')

请注意,在执行任何 type 转换后检查是否包含在 choices 容器中,因此 choices 容器中的对象类型应与 匹配]type 指定:

>>> 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)

任何容器都可以作为 choices 值传递,所以 list 对象、set 对象和自定义容器都被支持。


必需的

通常,argparse 模块假设像 -f--bar 表示 optional 参数,这些参数在命令行中总是可以省略的。 要使选项 required,可以为 add_argument()required= 关键字参数指定 True

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', required=True)
>>> parser.parse_args(['--foo', 'BAR'])
Namespace(foo='BAR')
>>> parser.parse_args([])
usage: [-h] --foo FOO
: error: the following arguments are required: --foo

如示例所示,如果一个选项被标记为 required,如果命令行中不存在该选项,则 parse_args() 将报告错误。

笔记

必需的选项通常被认为是不好的形式,因为用户希望 optionsoptional,因此应该尽可能避免它们。


帮助

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

>>> 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

help 字符串可以包含各种格式说明符,以避免重复诸如程序名称或参数 default 之类的内容。 可用的说明符包括程序名称、%(prog)sadd_argument() 的大多数关键字参数,例如 %(default)s%(type)s 等:

>>> 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

由于帮助字符串支持 %-f 格式,如果您希望文字 % 出现在帮助字符串中,则必须将其转义为 %%

argparse 通过将 help 值设置为 argparse.SUPPRESS 来支持使某些选项的帮助条目静音:

>>> 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

元变量

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

>>> 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 指定替代名称:

>>> 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 仅更改 displayed 名称 - parse_args() 对象上的属性名称仍由 dest 值决定.

nargs 的不同值可能会导致元变量被多次使用。 为 metavar 提供一个元组为每个参数指定不同的显示:

>>> 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

目的地

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

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('bar')
>>> parser.parse_args(['XXX'])
Namespace(bar='XXX')

对于可选参数操作,dest 的值通常是从选项字符串中推断出来的。 ArgumentParser 通过取第一个长选项字符串并剥离初始 -- 字符串来生成 dest 的值。 如果未提供长选项字符串,则 dest 将通过剥离初始 - 字符从第一个短选项字符串派生。 任何内部 - 字符都将转换为 _ 字符以确保字符串是有效的属性名称。 下面的示例说明了这种行为:

>>> 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 允许提供自定义属性名称:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', dest='bar')
>>> parser.parse_args('--foo XXX'.split())
Namespace(bar='XXX')

动作类

Action 类实现了 Action API,这是一个可调用的,它返回一个可调用的,它处理来自命令行的参数。 任何遵循此 API 的对象都可以作为 action 参数传递给 add_argument()

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_strings”、“default”、“type”、“required”、“help”等。 定义。 确保定义这些属性的最简单方法是调用 Action.__init__

Action 实例应该是可调用的,因此子类必须覆盖 __call__ 方法,该方法应该接受四个参数:

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

__call__ 方法可以执行任意操作,但通常会根据 destvaluesnamespace 上设置属性。


parse_args() 方法

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

将参数字符串转换为对象并将它们分配为命名空间的属性。 返回填充的命名空间。

之前对 add_argument() 的调用确定了创建哪些对象以及如何分配它们。 有关详细信息,请参阅 add_argument() 的文档。

  • args - 要解析的字符串列表。 默认值取自 sys.argv

  • namespace - 获取属性的对象。 默认值是一个新的空 Namespace 对象。

选项值语法

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

>>> 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)

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

>>> parser.parse_args(['--foo=FOO'])
Namespace(foo='FOO', x=None)

对于短选项(选项只有一个字符长),可以连接选项及其值:

>>> parser.parse_args(['-xX'])
Namespace(foo=None, x='X')

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

>>> 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')

无效参数

在解析命令行时,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

包含 - 的参数

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

>>> 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()之后是位置参数:

>>> parser.parse_args(['--', '-f'])
Namespace(foo='-f', one=None)

参数缩写(前缀匹配)

parse_args() 方法 默认情况下 允许将长选项缩写为前缀,如果缩写是明确的(前缀匹配唯一选项):

>>> 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 来禁用此功能。


超越sys.argv

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

>>> 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])

命名空间对象

class argparse.Namespace
parse_args() 默认使用的简单类来创建一个包含属性的对象并返回它。

这个类故意简单,只是一个具有可读字符串表示的 object 子类。 如果您更喜欢类似 dict 的属性视图,您可以使用标准的 Python 习语,vars()

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> args = parser.parse_args(['--foo', 'BAR'])
>>> vars(args)
{'foo': 'BAR'}

ArgumentParser 将属性分配给已经存在的对象,而不是新的 Namespace 对象也可能很有用。 这可以通过指定 namespace= 关键字参数来实现:

>>> class C:
...     pass
...
>>> c = C()
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> parser.parse_args(args=['--foo', 'BAR'], namespace=c)
>>> c.foo
'BAR'

其他公用事业

子命令

ArgumentParser.add_subparsers([title][, description][, prog][, parser_class][, action][, option_string][, dest][, required][, help][, metavar])

许多程序将它们的功能拆分为多个子命令,例如,svn 程序可以调用子命令,如 svn checkoutsvn update 和 [ X168X]。 当程序执行需要不同类型命令行参数的多个不同功能时,以这种方式拆分功能可能是一个特别好的主意。 ArgumentParser 支持使用 add_subparsers() 方法创建此类子命令。 add_subparsers() 方法通常不带参数调用,并返回一个特殊的动作对象。 这个对象有一个方法,add_parser(),它接受一个命令名称和任何 ArgumentParser 构造函数参数,并返回一个可以像往常一样修改的 ArgumentParser 对象。

参数说明:

  • title - 帮助输出中子解析器组的标题; 默认情况下“子命令”如果提供了描述,否则使用标题作为位置参数

  • description - 帮助输出中子解析器组的描述,默认情况下 None

  • prog - 将与子命令帮助一起显示的使用信息,默认情况下程序的名称和 subparser 参数之前的任何位置参数

  • parser_class - 将用于创建子解析器实例的类,默认情况下当前解析器的类(例如 参数解析器)

  • action - 在命令行遇到此参数时要采取的基本操作类型

  • dest - 将存储子命令名称的属性名称; 默认 None 并且不存储任何值

  • required - 是否必须提供子命令,默认情况下 False(在 3.7 中添加)

  • help - 帮助输出中子解析器组的帮助,默认情况下 None

  • metavar - 在帮助中显示可用子命令的字符串; 默认情况下它是 None 并以 {cmd1, cmd2, ..} 形式呈现子命令

一些示例用法:

>>> # 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命令时,只有foobar属性存在,而当指定b命令时,仅存在 foobaz 属性。

类似地,当从子解析器请求帮助消息时,只会打印该特定解析器的帮助。 帮助消息将不包括父解析器或兄弟解析器消息。 (但是,可以通过将 help= 参数提供给上述 add_parser() 来给出每个子解析器命令的帮助消息。)

>>> 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() 方法还支持 titledescription 关键字参数。 当存在任何一个时,子解析器的命令将出现在帮助输出中它们自己的组中。 例如:

>>> 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 支持额外的 aliases 参数,它允许多个字符串引用同一个子解析器。 这个例子,像 svn,别名 co 作为 checkout 的简写:

>>> 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 函数。 例如:

>>> # 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 关键字参数将起作用:

>>> 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')

在 3.7 版更改:新增 required 关键字参数。


文件类型对象

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

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

>>> 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 可读 FileType 对象和 sys.stdout 可写 FileType对象:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('infile', type=argparse.FileType('r'))
>>> parser.parse_args(['-'])
Namespace(infile=<_io.TextIOWrapper name='<stdin>' encoding='UTF-8'>)

3.4 版新功能:encodingserrors 关键字参数。


参数组

ArgumentParser.add_argument_group(title=None, description=None)

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

>>> 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() 方法接受 titledescription 参数,可用于自定义此显示:

>>> 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

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


相互排斥

ArgumentParser.add_mutually_exclusive_group(required=False)

创建一个互斥组。 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')
>>> 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() 方法还接受 required 参数,以指示至少需要一个互斥参数:

>>> 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()titledescription 参数。


解析器默认值

ArgumentParser.set_defaults(**kwargs)

大多数情况下,parse_args() 返回的对象的属性将通过检查命令行参数和参数操作来完全确定。 set_defaults() 允许添加一些无需检查命令行即可确定的其他属性:

>>> 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)

请注意,解析器级别的默认值始终覆盖参数级别的默认值:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default='bar')
>>> parser.set_defaults(foo='spam')
>>> parser.parse_args([])
Namespace(foo='spam')

当使用多个解析器时,解析器级别的默认值特别有用。 有关此类型的示例,请参阅 add_subparsers() 方法。

ArgumentParser.get_default(dest)

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

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default='badger')
>>> parser.get_default('foo')
'badger'


打印帮助

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

ArgumentParser.print_usage(file=None)
打印有关如何在命令行上调用 ArgumentParser 的简要说明。 如果 fileNone,则假定为 sys.stdout
ArgumentParser.print_help(file=None)
打印一条帮助消息,包括程序使用情况和有关使用 ArgumentParser 注册的参数的信息。 如果 fileNone,则假定为 sys.stdout

这些方法还有一些变体,它们只是返回一个字符串而不是打印它:

ArgumentParser.format_usage()
返回一个字符串,其中包含有关如何在命令行上调用 ArgumentParser 的简要说明。
ArgumentParser.format_help()
返回一个包含帮助消息的字符串,包括程序使用情况和有关使用 ArgumentParser 注册的参数的信息。


部分解析

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

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

>>> 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'])

警告

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


自定义文件解析

ArgumentParser.convert_arg_line_to_args(arg_line)

从文件中读取的参数(请参阅 ArgumentParser 构造函数的 fromfile_prefix_chars 关键字参数)每行读取一个参数。 convert_arg_line_to_args() 可以被覆盖以进行更高级的阅读。

此方法采用单个参数 arg_line,它是从参数文件中读取的字符串。 它返回从此字符串解析的参数列表。 该方法按顺序从参数文件中读取的每一行调用一次。

此方法的一个有用覆盖是将每个空格分隔的单词视为参数。 以下示例演示了如何执行此操作:

class MyArgumentParser(argparse.ArgumentParser):
    def convert_arg_line_to_args(self, arg_line):
        return arg_line.split()


退出方法

ArgumentParser.exit(status=0, message=None)

此方法终止程序,以指定的 状态 退出,如果给定,则在此之前打印 消息 。 用户可以覆盖此方法以不同方式处理这些步骤:

class ErrorCatchingArgumentParser(argparse.ArgumentParser):
    def exit(self, status=0, message=None):
        if status:
            raise Exception(f'Exiting because of an error: {message}')
        exit(status)
ArgumentParser.error(message)
此方法将包含 消息 的用法消息打印到标准错误,并以状态代码 2 终止程序。


混合解析

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.REMAINDER 和包含可选和位置的互斥组。

下面的例子展示了 parse_known_args()parse_intermixed_args() 的区别:前者返回 ['2', '3'] 作为未解析的参数,而后者将所有位置收集到 rest

>>> 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() 如果还有任何未解析的参数字符串,则会引发错误。

3.7 版中的新功能。


升级 optparse 代码

最初,argparse 模块试图保持与 optparse 的兼容性。 然而,optparse 很难透明地扩展,特别是在支持新的 nargs= 说明符和更好的使用消息所需的更改时。 当 optparse 中的大部分内容都被复制粘贴或猴子修补时,尝试保持向后兼容性似乎不再可行。

argparse 模块以多种方式改进了标准库 optparse 模块,包括:

  • 处理位置参数。
  • 支持子命令。
  • 允许替代选项前缀,如 +/
  • 处理零个或多个和一个或多个样式参数。
  • 生成更多信息丰富的使用消息。
  • 为自定义 typeaction 提供更简单的界面。

optparseargparse 的部分升级路径:

  • 将所有 optparse.OptionParser.add_option() 调用替换为 ArgumentParser.add_argument() 调用。
  • (options, args) = parser.parse_args() 替换为 args = parser.parse_args(),并为位置参数添加额外的 ArgumentParser.add_argument() 调用。 请记住,以前称为 options,现在在 argparse 上下文中称为 args
  • 使用 parse_intermixed_args() 代替 parse_args() 替换 optparse.OptionParser.disable_interspersed_args()
  • 将回调操作和 callback_* 关键字参数替换为 typeaction 参数。
  • type 关键字参数的字符串名称替换为相应的类型对象(例如 int、float、complex 等)。
  • optparse.Values 替换为 命名空间 ,将 optparse.OptionErroroptparse.OptionValueError 替换为 ArgumentError
  • 将带有隐式参数的字符串(例如 %default%prog)替换为标准 Python 语法,以使用字典来格式化字符串,即 %(default)s%(prog)s
  • 将 OptionParser 构造函数 version 参数替换为对 parser.add_argument('--version', action='version', version='<the version>') 的调用。