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

3.2 版本新增。

源代码: Lib/argparse.py

注解

虽然 argparse 是实现基本命令行应用程序的默认推荐标准库模块,但对于其命令行应用程序的行为有更严格要求的作者可能会发现它没有提供必要的控制级别。当 argparse 不支持应用程序所需的行为时(例如完全禁用对穿插选项和位置参数的支持,或接受以 - 开头的选项参数值,即使它们对应于另一个定义的选项),请参阅 选择参数解析库 以考虑替代方案。


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

argparse 模块对命令行界面的支持是围绕 argparse.ArgumentParser 的实例构建的。它是参数规范的容器,并具有适用于整个解析器的选项

parser = argparse.ArgumentParser(
                    prog='ProgramName',
                    description='What the program does',
                    epilog='Text at the bottom of help')

ArgumentParser.add_argument() 方法将各个参数规范附加到解析器。它支持位置参数、接受值的选项以及开/关标志

parser.add_argument('filename')           # positional argument
parser.add_argument('-c', '--count')      # option that takes a value
parser.add_argument('-v', '--verbose',
                    action='store_true')  # on/off flag

ArgumentParser.parse_args() 方法运行解析器,并将提取的数据放入 argparse.Namespace 对象中

args = parser.parse_args()
print(args.filename, args.count, args.verbose)

注解

如果您正在寻找有关如何将 optparse 代码升级到 argparse 的指南,请参阅 升级 Optparse 代码

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, exit_on_error=True)

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

  • prog - 程序的名称(默认值:os.path.basename(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

  • exit_on_error - 确定当发生错误时,ArgumentParser 是否退出并显示错误信息。(默认值:True

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

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

在 3.9 版本中更改: 添加了 exit_on_error 参数。

以下部分描述了如何使用这些参数中的每一个。

prog

默认情况下,ArgumentParser 根据 Python 解释器的运行方式计算要在帮助消息中显示的程序名称

  • 如果将文件作为参数传递,则为 sys.argv[0]base name

  • 如果将目录或 zipfile 作为参数传递,则为 Python 解释器名称后跟 sys.argv[0]

  • 如果使用了 -m 选项,则为 Python 解释器名称后跟 -m 后跟模块或包名称。

此默认值几乎总是理想的,因为它会使帮助消息与在命令行上调用程序时使用的字符串匹配。但是,要更改此默认行为,可以使用 prog= 参数为 ArgumentParser 提供另一个值。

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

options:
 -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]

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

用法

默认情况下,ArgumentParser 从其包含的参数计算用法消息。可以使用 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

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

%(prog)s 格式说明符可用于在用法消息中填充程序名称。

描述

大多数对 ArgumentParser 构造函数的调用都将使用 description= 关键字参数。此参数简要描述程序的作用以及它的工作原理。在帮助消息中,描述显示在命令行用法字符串和各种参数的帮助消息之间。

默认情况下,描述将自动换行,使其适合给定的空间。要更改此行为,请参阅 formatter_class 参数。

后记

某些程序喜欢在参数描述之后显示程序的其他描述。可以使用 epilog= 参数为 ArgumentParser 指定此类文本。

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

options:
 -h, --help  show this help message and exit

And that's how you'd foo a bar

description 参数一样,默认情况下,epilog= 文本也会自动换行,但是可以通过 formatter_class 参数为 ArgumentParser 调整此行为。

父解析器

有时,多个解析器共享一组常见的参数。与其重复定义这些参数,不如使用包含所有共享参数的单个解析器,并将其传递给 ArgumentParserparents= 参数。 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

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

options:
 -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 ...]

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

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

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

前缀字符

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

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

>>> with open('args.txt', 'w', encoding=sys.getfilesystemencoding()) 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']

ArgumentParser 使用文件系统编码和错误处理程序读取包含参数的文件。

fromfile_prefix_chars= 参数的默认值为 None,这意味着参数永远不会被视为文件引用。

在 3.12 版本中更改:ArgumentParser 更改了编码和错误,以从默认值(例如,locale.getpreferredencoding(False)"strict")读取参数文件到文件系统编码和错误处理程序。参数文件在 Windows 上应使用 UTF-8 编码,而不是 ANSI 代码页。

argument_default

通常,参数默认值可以通过将默认值传递给 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

通常,当你将参数列表传递给 parse_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 版本中添加。

conflict_handler

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

有时(例如,在使用 父类 时),简单地使用相同的选项字符串覆盖任何较旧的参数可能很有用。为了获得此行为,可以将值 '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]

options:
 -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 对象会添加一个选项,该选项仅显示解析器的帮助消息。如果在命令行中提供 -h--help,则会打印 ArgumentParser 帮助。

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

>>> parser = argparse.ArgumentParser(prog='PROG', add_help=False)
>>> parser.add_argument('--foo', help='foo help')
>>> parser.print_help()
usage: PROG [--foo FOO]

options:
 --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]

options:
  +h, ++help  show this help message and exit

exit_on_error

通常,当你将无效的参数列表传递给 parse_args() 方法时,它会将消息打印到 sys.stderr 并以状态码 2 退出。

如果用户希望手动捕获错误,则可以通过将 exit_on_error 设置为 False 来启用此功能

>>> parser = argparse.ArgumentParser(exit_on_error=False)
>>> parser.add_argument('--integers', type=int)
_StoreAction(option_strings=['--integers'], dest='integers', nargs=None, const=None, default=None, type=<class 'int'>, choices=None, help=None, metavar=None)
>>> try:
...     parser.parse_args('--integers a'.split())
... except argparse.ArgumentError:
...     print('Catching an argumentError')
...
Catching an argumentError

在 3.9 版本中添加。

add_argument() 方法

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

定义如何解析单个命令行参数。每个参数都有其自己的更详细的描述,但简而言之,它们是

  • 名称或标志 - 名称或选项字符串列表,例如 'foo''-f', '--foo'

  • action - 当在命令行中遇到此参数时要执行的基本操作类型。

  • nargs - 应该使用的命令行参数的数量。

  • const - 某些 actionnargs 选择所需的常量值。

  • default - 如果命令行中没有该参数,并且如果命名空间对象中没有该参数,则生成的值。

  • type - 应该将命令行参数转换为的类型。

  • choices - 参数的允许值序列。

  • required - 是否可以省略命令行选项(仅限可选)。

  • help - 对参数作用的简要描述。

  • metavar - 用法消息中参数的名称。

  • dest - 要添加到由 parse_args() 返回的对象中的属性的名称。

  • deprecated - 是否不建议使用该参数。

以下部分描述了如何使用这些参数中的每一个。

名称或标志

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

action

ArgumentParser 对象将命令行参数与动作关联。 这些动作几乎可以对与之关联的命令行参数执行任何操作,尽管大多数动作只是将属性添加到 parse_args() 返回的对象。 action 关键字参数指定应如何处理命令行参数。 提供的动作有

  • 'store' - 这只是存储参数的值。 这是默认操作。

  • 'store_const' - 这会存储由 const 关键字参数指定的值;请注意,const 关键字参数默认为 None'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'>])
    
  • 'extend' - 此操作存储一个列表,并将多值参数列表中的每个项附加到该列表。 'extend' 操作通常与 nargs 关键字参数值 '+''*' 一起使用。 请注意,当 nargsNone(默认值)或 '?' 时,参数字符串的每个字符都将附加到列表中。用法示例

    >>> 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 版本中添加。

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

只有使用命令行参数的操作(例如 'store''append''extend')才能与位置参数一起使用。

class argparse.BooleanOptionalAction

您还可以通过传递一个 Action 子类或其他实现相同接口的对象来指定任意操作。BooleanOptionalActionargparse 中可用,并添加了对布尔操作(如 --foo--no-foo)的支持。

>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action=argparse.BooleanOptionalAction)
>>> parser.parse_args(['--no-foo'])
Namespace(foo=False)

在 3.9 版本中添加。

创建自定义操作的推荐方法是扩展 Action,覆盖 __call__() 方法,并可以选择覆盖 __init__()format_usage() 方法。您还可以使用 register() 方法注册自定义操作,并通过其注册名称引用它们。

自定义操作的示例

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

有关更多详细信息,请参阅 Action

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
    

如果未提供 nargs 关键字参数,则消耗的参数数量由 action 确定。 通常,这意味着将消耗单个命令行参数,并生成单个项(而不是列表)。 不使用命令行参数的操作(例如 'store_const')设置 nargs=0

const

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

  • 当使用 action='store_const'action='append_const' 调用 add_argument() 时。这些操作将 const 值添加到由 parse_args() 返回的对象的属性之一。有关示例,请参阅 action 说明。如果未向 add_argument() 提供 const,则它将接收 None 的默认值。

  • 当使用选项字符串(如 -f--foo)调用 add_argument() 并且 nargs='?' 时,将创建一个可选参数,该参数可以后跟零个或一个命令行参数。在解析命令行时,如果遇到选项字符串但后面没有跟随命令行参数,则将假定 const 的值为 None。有关示例,请参阅 nargs 的描述。

在 3.11 版本中更改: 默认情况下 const=None,包括当 action='append_const'action='store_const' 时。

default

所有可选参数和某些位置参数都可以在命令行中省略。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)

如果目标命名空间已设置了属性,则 action *default* 不会覆盖它。

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

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

对于 required 参数,将忽略 default 值。例如,这适用于 nargs 值不是 ?* 的位置参数,或标记为 required=True 的可选参数。

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

type

默认情况下,解析器将命令行参数读取为简单的字符串。但是,命令行字符串通常应解释为另一种类型,例如 floatintadd_argument()type 关键字允许执行任何必要的类型检查和类型转换。

如果 type 关键字与 default 关键字一起使用,则仅当 default 是字符串时才应用类型转换器。

type 的参数可以是接受单个字符串的可调用对象,也可以是已注册类型的名称(请参阅 register())。如果函数引发 ArgumentTypeErrorTypeErrorValueError,则会捕获异常并显示格式良好的错误消息。不处理其他异常类型。

常见的内置类型和函数可以用作类型转换器。

import argparse
import pathlib

parser = argparse.ArgumentParser()
parser.add_argument('count', type=int)
parser.add_argument('distance', type=float)
parser.add_argument('street', type=ascii)
parser.add_argument('code_point', type=ord)
parser.add_argument('dest_file', type=argparse.FileType('w', encoding='latin-1'))
parser.add_argument('datapath', type=pathlib.Path)

用户定义的函数也可以使用。

>>> def hyphenated(string):
...     return '-'.join([word[:4] for word in string.casefold().split()])
...
>>> parser = argparse.ArgumentParser()
>>> _ = parser.add_argument('short_title', type=hyphenated)
>>> parser.parse_args(['"The Tale of Two Cities"'])
Namespace(short_title='"the-tale-of-two-citi')

不建议将 bool() 函数用作类型转换器。它所做的只是将空字符串转换为 False,将非空字符串转换为 True。这通常不是想要的。

通常,type 关键字是一种便利功能,仅应用于简单的转换,这些转换只能引发三个支持的异常之一。任何具有更有趣的错误处理或资源管理的功能都应在解析参数后在下游进行。

例如,JSON 或 YAML 转换具有复杂的错误情况,需要比 type 关键字提供的更好的报告。JSONDecodeError 的格式将不佳,并且根本不会处理 FileNotFoundError 异常。

即使 FileType 在与 type 关键字一起使用时也有其局限性。如果一个参数使用 FileType,然后后续参数失败,则会报告错误,但不会自动关闭该文件。在这种情况下,最好等到解析器运行后,然后使用 with 语句来管理文件。

对于仅针对固定值集进行检查的类型检查器,请考虑改用 choices 关键字。

choices

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

>>> 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 匹配。

任何序列都可以作为 *choices* 值传递,因此支持 list 对象、tuple 对象和自定义序列。

不建议使用 enum.Enum,因为它很难控制其在用法、帮助和错误消息中的外观。

格式化的 choices 会覆盖通常从 *dest* 派生的默认 *metavar*。这通常是你想要的,因为用户永远不会看到 *dest* 参数。如果此显示不理想(可能因为有很多选择),只需指定一个显式的 metavar

required

通常,argparse 模块假定诸如 -f--bar 之类的标志表示 *可选* 参数,这些参数始终可以在命令行中省略。要使选项为 *必需* 的,可以为 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() 将报告错误。

注解

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

help

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

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)

options:
 -h, --help  show this help message and exit

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

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

>>> parser = argparse.ArgumentParser(prog='frobble')
>>> parser.add_argument('--foo', help=argparse.SUPPRESS)
>>> parser.print_help()
usage: frobble [-h]

options:
  -h, --help  show this help message and exit

metavar

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

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

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

请注意,metavar 仅更改显示的名称 - parse_args() 对象上属性的名称仍然由 dest 值确定。

nargs 的不同值可能会导致多次使用 metavar。向 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]

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

dest

大多数 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')

deprecated

在项目的生命周期中,可能需要从命令行删除某些参数。在删除它们之前,您应该通知用户这些参数已弃用,并且将被删除。默认值为 Falseadd_argument()deprecated 关键字参数指定该参数是否已弃用,并将在未来删除。对于参数,如果 deprecatedTrue,则当使用该参数时,将向 sys.stderr 打印警告。

>>> import argparse
>>> parser = argparse.ArgumentParser(prog='snake.py')
>>> parser.add_argument('--legs', default=0, type=int, deprecated=True)
>>> parser.parse_args([])
Namespace(legs=0)
>>> parser.parse_args(['--legs', '4'])  
snake.py: warning: option '--legs' is deprecated
Namespace(legs=4)

在 3.13 版本中添加。

Action 类

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)

Action 对象由 ArgumentParser 使用,以表示从命令行解析一个或多个字符串的单个参数所需的信息。Action 类必须接受两个位置参数,以及传递给 ArgumentParser.add_argument() 的任何关键字参数,除了 action 本身。

Action 的实例(或传递给 action 参数的任何可调用对象的返回值)应具有已定义的属性 destoption_stringsdefaulttyperequiredhelp 等。确保定义这些属性的最简单方法是调用 Action.__init__()

__call__(parser, namespace, values, option_string=None)

Action 实例应该是可调用的,因此子类必须重写 __call__() 方法,该方法应接受四个参数。

  • parser - 包含此操作的 ArgumentParser 对象。

  • namespace - 将由 parse_args() 返回的 Namespace 对象。大多数操作使用 setattr() 将属性添加到此对象。

  • values - 关联的命令行参数,并应用了任何类型转换。类型转换使用 type 关键字参数指定给 add_argument()

  • option_string - 用于调用此操作的选项字符串。option_string 参数是可选的,如果该操作与位置参数关联,则该参数将不存在。

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

format_usage()

Action 子类可以定义一个 format_usage() 方法,该方法不接受任何参数并返回一个字符串,该字符串将在打印程序用法时使用。如果未提供此类方法,则将使用合理的默认值。

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)

有关更多详细信息,另请参阅 关于歧义参数的 argparse 指南

参数缩写(前缀匹配)

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 子类。如果你希望具有属性的类似字典的视图,可以使用标准 Python 惯用法 vars()

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

将属性分配给已存在的对象,而不是新的 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][, dest][, required][, help][, metavar])

许多程序将其功能划分为多个子命令,例如,svn 程序可以调用诸如 svn checkoutsvn updatesvn commit 之类的子命令。当程序执行需要不同类型的命令行参数的多个不同功能时,以这种方式划分功能可能是一个特别好的主意。ArgumentParser 支持使用 add_subparsers() 方法创建此类子命令。add_subparsers() 方法通常在没有参数的情况下调用,并返回一个特殊的操作对象。此对象具有一个单独的方法 add_parser(),该方法接受命令名称和任何 ArgumentParser 构造函数参数,并返回一个可以照常修改的 ArgumentParser 对象。

参数描述

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

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

  • prog - 将与子命令帮助一起显示的用法信息,默认值为程序名称和子解析器参数之前的任何位置参数

  • parser_class - 将用于创建子解析器实例的类,默认值为当前解析器的类(例如,ArgumentParser

  • 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='subcommand 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=('X', 'Y', 'Z'), 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 属性。

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

>>> parser.parse_args(['--help'])
usage: PROG [-h] [--foo] {a,b} ...

positional arguments:
  {a,b}   subcommand help
    a     a help
    b     b help

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

options:
  -h, --help  show this help message and exit

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

options:
  -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} ...

options:
  -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_parser() 还支持一个额外的 *deprecated* 参数,该参数允许弃用子解析器。

>>> import argparse
>>> parser = argparse.ArgumentParser(prog='chicken.py')
>>> subparsers = parser.add_subparsers()
>>> run = subparsers.add_parser('run')
>>> fly = subparsers.add_parser('fly', deprecated=True)
>>> parser.parse_args(['fly'])  
chicken.py: warning: command 'fly' is deprecated
Namespace()

在 3.13 版本中添加。

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

>>> # subcommand 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(required=True)
>>>
>>> # 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* 关键字参数。

FileType 对象

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

FileType 工厂创建可以传递给 ArgumentParser.add_argument() 的 type 参数的对象。将 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 对象理解伪参数 '-',并自动将其转换为可读 FileType 对象的 sys.stdin 和可写 FileType 对象的 sys.stdout

>>> 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 版本中更改: 添加了 *encodings* 和 *errors* 参数。

参数组

ArgumentParser.add_argument_group(title=None, description=None, *[, argument_default][, conflict_handler])

默认情况下,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() 方法返回一个参数组对象,该对象具有与常规 ArgumentParser 相同的 add_argument() 方法。当将参数添加到组中时,解析器会像处理普通参数一样对待它,但在帮助消息中将参数显示在单独的组中。add_argument_group() 方法接受 *title* 和 *description* 参数,这些参数可用于自定义此显示。

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

可选的,仅限关键字的参数 argument_defaultconflict_handler 允许对参数组的行为进行更细粒度的控制。这些参数的含义与 ArgumentParser 构造函数中的含义相同,但专门应用于参数组而不是整个解析器。

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

在 3.11 版本中更改: 在参数组上调用 add_argument_group() 已被弃用。此功能从未得到支持,并且并非始终正常工作。该功能通过继承意外地存在于 API 上,将来将被删除。

互斥

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() 的 *title* 和 *description* 参数。但是,可以将互斥组添加到具有标题和描述的参数组中。例如:

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> group = parser.add_argument_group('Group title', 'Group description')
>>> exclusive_group = group.add_mutually_exclusive_group(required=True)
>>> exclusive_group.add_argument('--foo', help='foo help')
>>> exclusive_group.add_argument('--bar', help='bar help')
>>> parser.print_help()
usage: PROG [-h] (--foo FOO | --bar BAR)

options:
  -h, --help  show this help message and exit

Group title:
  Group description

  --foo FOO   foo help
  --bar BAR   bar help

3.11 版本已更改: 在互斥组上调用 add_argument_group()add_mutually_exclusive_group() 已被弃用。这些功能从未被支持,并且并不总是能正常工作。这些函数是通过继承意外地存在于 API 中,将来会被移除。

解析器默认值

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)

此方法会终止程序,并以指定的 status 退出,如果给定,它会在之前将 message 打印到 sys.stderr。用户可以重写此方法以不同方式处理这些步骤。

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)

此方法会向 sys.stderr 打印用法消息,包括 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 功能,如果使用不支持的功能,将会引发异常。 特别是,不支持子解析器以及包含可选参数和位置参数的互斥组。

下面的示例显示了 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 版本新增。

注册自定义类型或操作

ArgumentParser.register(registry_name, value, object)

有时,在错误消息中使用自定义字符串以提供更友好的用户输出是可取的。 在这些情况下,可以使用 register() 向解析器注册自定义操作或类型,并允许您通过其注册名称而不是其可调用名称来引用该类型。

register() 方法接受三个参数 - registry_name,指定将存储对象的内部注册表(例如,action, type),value,它是注册对象的键,以及 object,即要注册的可调用对象。

以下示例显示了如何向解析器注册自定义类型

>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> parser.register('type', 'hexadecimal integer', lambda s: int(s, 16))
>>> parser.add_argument('--foo', type='hexadecimal integer')
_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type='hexadecimal integer', choices=None, required=False, help=None, metavar=None, deprecated=False)
>>> parser.parse_args(['--foo', '0xFA'])
Namespace(foo=250)
>>> parser.parse_args(['--foo', '1.2'])
usage: PROG [-h] [--foo FOO]
PROG: error: argument --foo: invalid 'hexadecimal integer' value: '1.2'

异常

exception argparse.ArgumentError

创建或使用参数(可选或位置参数)时发生的错误。

此异常的字符串值是消息,并补充了导致该错误的参数的信息。

exception argparse.ArgumentTypeError

当将命令行字符串转换为类型时出现问题时引发。

指南和教程