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, *, suggest_on_error=False, color=True)¶
创建一个新的
ArgumentParser
对象。所有参数都应当作为关键字参数传入。每个参数在下面都有更详细的描述,简而言之,它们是:prog - 程序的名称(默认值:从
__main__
模块属性和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
)suggest_on_error - 为拼写错误的参数选项和子解析器名称启用建议(默认值:
False
)color - 允许彩色输出(默认值:
True
)
在 3.5 版更改: 增加了 allow_abbrev 形参。
在 3.8 版更改: 在之前的版本中,allow_abbrev 还会禁用短标志的分组,例如
-vv
表示-v -v
。在 3.9 版更改: 增加了 exit_on_error 形参。
在 3.14 版更改: 增加了 suggest_on_error 和 color 参数。
以下各节描述了如何使用其中的每一个。
prog¶
默认情况下,ArgumentParser
会根据 Python 解释器的运行方式计算要在帮助消息中显示的程序名称:
如果传入的是文件作为参数,则为
sys.argv[0]
的基本名称
。如果传入的是目录或 zip 文件作为参数,则为 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]
、__main__
模块属性还是从 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
在 3.14 版更改: 默认的 prog
值现在反映了 __main__
的实际执行方式,而不再总是 os.path.basename(sys.argv[0])
。
usage¶
默认情况下,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
格式说明符可用于在用法消息中填充程序名称。
当为主解析器指定自定义用法消息时,你可能还想考虑将 prog
参数传递给 add_subparsers()
,或者将 prog
和 usage
参数传递给 add_parser()
,以确保在子解析器之间保持一致的命令前缀和用法信息。
description¶
大多数对 ArgumentParser
构造函数的调用都会使用 description=
关键字参数。此参数简要描述了程序的功能及其工作原理。在帮助消息中,描述显示在命令行用法字符串和各种参数的帮助消息之间。
默认情况下,描述将被自动换行以适应给定的空间。要更改此行为,请参见 formatter_class 参数。
epilog¶
一些程序喜欢在参数描述之后显示对程序的额外描述。可以使用 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 参数调整此行为。
parents¶
有时,几个解析器会共享一组共同的参数。与其重复定义这些参数,不如使用一个包含所有共享参数的解析器,并将其传递给 ArgumentParser
的 parents=
参数。 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=
传递解析器之前,必须完全初始化它们。如果在子解析器创建后更改了父解析器,这些更改将不会反映在子解析器中。
formatter_class¶
ArgumentParser
对象允许通过指定一个备用的格式化类来自定义帮助信息的格式。目前,有四个这样的类:
- class argparse.RawDescriptionHelpFormatter¶
- class argparse.RawTextHelpFormatter¶
- class argparse.ArgumentDefaultsHelpFormatter¶
- class argparse.MetavarTypeHelpFormatter¶
RawDescriptionHelpFormatter
和 RawTextHelpFormatter
提供了更多对文本描述显示方式的控制。默认情况下,ArgumentParser
对象会在命令行帮助消息中对 description 和 epilog 文本进行自动换行。
>>> 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=
传入表示 description 和 epilog 已经正确格式化,不应进行自动换行。
>>> 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
prefix_chars¶
大多数命令行选项会使用 -
作为前缀,例如 -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
构造函数提供了 fromfile_prefix_chars=
参数,那么以任何指定字符开头的参数都将被视为文件,并被其包含的参数所替换。例如:
>>> 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()
传递一个 `default` 值,或者通过调用带有特定名称-值对集合的 set_defaults()
方法来指定的。然而,有时为参数指定一个单一的解析器范围的默认值可能很有用。这可以通过向 ArgumentParser
传递 argument_default=
关键字参数来实现。例如,要在 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¶
通常,当你将一个参数列表传递给 ArgumentParser
的 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
有时(例如,在使用 parents 时),简单地用具有相同选项字符串的新参数覆盖任何旧参数可能会很有用。要实现此行为,可以将值 'resolve'
提供给 ArgumentParser
的 conflict_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
作为 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]
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¶
通常,当你将一个无效的参数列表传递给 ArgumentParser
的 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 版本中新增。
suggest_on_error¶
默认情况下,当用户传递一个无效的参数选项或子解析器名称时,ArgumentParser
将会携带错误信息退出,并在错误消息中列出允许的参数选项(如果已指定)或子解析器名称。
如果用户希望为拼写错误的参数选项和子解析器名称启用建议,可以通过将 suggest_on_error
设置为 True
来启用该功能。请注意,这仅适用于指定的 `choices` 是字符串的参数。
>>> parser = argparse.ArgumentParser(description='Process some integers.',
suggest_on_error=True)
>>> parser.add_argument('--action', choices=['sum', 'max'])
>>> parser.add_argument('integers', metavar='N', type=int, nargs='+',
... help='an integer for the accumulator')
>>> parser.parse_args(['--action', 'sumn', 1, 2, 3])
tester.py: error: argument --action: invalid choice: 'sumn', maybe you meant 'sum'? (choose from 'sum', 'max')
如果你正在编写需要与旧版 Python 兼容的代码,并希望在 suggest_on_error
可用时机会性地使用它,你可以在初始化解析器后将其设置为一个属性,而不是使用关键字参数。
>>> parser = argparse.ArgumentParser(description='Process some integers.')
>>> parser.suggest_on_error = True
在 3.14 版本加入。
color¶
默认情况下,帮助消息使用 ANSI 转义序列以彩色打印。如果你想要纯文本的帮助消息,可以在本地环境中禁用它,或者在参数解析器本身通过将 color
设置为 False
来禁用。
>>> parser = argparse.ArgumentParser(description='Process some integers.',
... color=False)
>>> parser.add_argument('--action', choices=['sum', 'max'])
>>> parser.add_argument('integers', metavar='N', type=int, nargs='+',
... help='an integer for the accumulator')
>>> parser.parse_args(['--help'])
在 3.14 版本加入。
add_argument() 方法¶
- ArgumentParser.add_argument(name or flags..., *[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest][, deprecated])¶
定义应如何解析单个命令行参数。每个参数在下面都有更详细的描述,但简而言之它们是:
name or flags - 一个名称或一个选项字符串列表,例如
'foo'
或'-f', '--foo'
。action - 在命令行中遇到此参数时要采取的基本操作类型。
nargs - 应该消耗的命令行参数的数量。
default - 如果参数在命令行中不存在且在命名空间对象中也不存在时产生的值。
type - 命令行参数应转换成的类型。
choices - 参数允许值的序列。
required - 命令行选项是否可以省略(仅限可选参数)。
help - 关于参数作用的简短描述。
metavar - 参数在用法消息中的名称。
dest - 要添加到
parse_args()
返回的对象中的属性名称。deprecated - 该参数的使用是否已弃用。
以下各节描述了如何使用其中的每一个。
name or flags¶
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
默认情况下,argparse
会自动处理参数的内部命名和显示名称,无需额外配置即可简化流程。因此,你不需要指定 dest 和 metavar 参数。dest 参数默认为参数名,其中下划线 _
替换了连字符 -
。metavar 参数默认为大写的名称。例如:
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo-bar')
>>> parser.parse_args(['--foo-bar', 'FOO-BAR']
Namespace(foo_bar='FOO-BAR')
>>> parser.print_help()
usage: [-h] [--foo-bar FOO-BAR]
optional arguments:
-h, --help show this help message and exit
--foo-bar FOO-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'
的特殊情况,分别用于存储值True
和False
。此外,它们分别创建默认值为False
和True
。>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', action='store_true') >>> parser.add_argument('--bar', action='store_false') >>> parser.add_argument('--baz', action='store_false') >>> parser.parse_args('--foo --bar'.split()) Namespace(foo=True, bar=False, baz=True)
'append'
- 这会将每个参数值附加到一个列表中。这对于允许一个选项被多次指定很有用。如果默认值是一个非空列表,解析后的值将从默认列表的元素开始,命令行中的任何值都将附加在这些默认值之后。用法示例:>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', action='append', default=['0']) >>> parser.parse_args('--foo 1 --foo 2'.split()) Namespace(foo=['0', '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 关键字参数值'+'
或'*'
一起使用。请注意,当 nargs 为None
(默认值)或'?'
时,参数字符串的每个字符都将被附加到列表中。用法示例:>>> 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)
请注意,*default* 将为
None
,除非显式设置为 *0*。'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
你也可以通过传递一个 Action
子类(例如 BooleanOptionalAction
)或其他实现相同接口的对象来指定任意动作。只有消耗命令行参数的动作(例如 'store'
、'append'
、'extend'
,或非零 nargs
的自定义动作)可以与位置参数一起使用。
创建自定义动作的推荐方法是扩展 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='?') >>> parser.add_argument('outfile', nargs='?') >>> parser.parse_args(['input.txt', 'output.txt']) Namespace(infile='input.txt', outfile='output.txt') >>> parser.parse_args(['input.txt']) Namespace(infile='input.txt', outfile=None) >>> parser.parse_args([]) Namespace(infile=None, outfile=None)
'*'
. 所有存在的命令行参数都会被收集到一个列表中。请注意,通常拥有多个带有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
动作是必需的常量值。它最常见的两个用途是:
当
add_argument()
被调用时带有action='store_const'
或action='append_const'
。这些动作将const
值添加到parse_args()
返回的对象的一个属性中。请参见 action 描述中的示例。如果未向add_argument()
提供const
,它将接收一个默认值None
。当
add_argument()
被调用时带有选项字符串(如-f
或--foo
)和nargs='?'
。这会创建一个可选参数,其后可以跟零个或一个命令行参数。解析命令行时,如果遇到选项字符串而后面没有命令行参数,将使用const
的值。请参见 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)
如果目标命名空间已经设置了一个属性,动作的 *default* 不会覆盖它。
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default=42)
>>> parser.parse_args([], namespace=argparse.Namespace(foo=101))
Namespace(foo=101)
如果 default
值是字符串,解析器会像解析命令行参数一样解析该值。特别是,如果提供了 type 转换参数,解析器会在设置 Namespace
返回值的属性之前应用该转换。否则,解析器会按原样使用该值。
>>> 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
值会被忽略。例如,这适用于 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¶
默认情况下,解析器将命令行参数作为简单字符串读入。然而,命令行字符串通常应该被解释为另一种类型,例如 float
或 int
。add_argument()
的 type
关键字允许执行任何必要的类型检查和类型转换。
如果 type 关键字与 default 关键字一起使用,类型转换器仅在默认值是字符串时应用。
type
的参数可以是一个接受单个字符串的可调用对象,或者是一个已注册类型的名称(参见 register()
)。如果该函数引发 ArgumentTypeError
、TypeError
或 ValueError
,异常会被捕获并显示一个格式良好的错误消息。其他异常类型则不被处理。
常见的内置类型和函数可以用作类型转换器:
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('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¶
一些命令行参数应该从一个受限的值集合中选择。这可以通过将一个序列对象作为 *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')
任何序列都可以作为 *choices* 的值传递,因此 list
对象、tuple
对象和自定义序列都支持。
不推荐使用 enum.Enum
,因为它很难控制其在用法、帮助和错误消息中的外观。
请注意,*choices* 是在任何 type 转换执行之后进行检查的,因此 *choices* 中的对象应与指定的 type 匹配。这可能使 *choices* 在用法、帮助或错误消息中显得不熟悉。
为了保持 *choices* 的用户友好性,可以考虑使用一个自定义的类型包装器来转换和格式化值,或者省略 type 并在你的应用程序代码中处理转换。
格式化的选项会覆盖默认的 *metavar*,后者通常派生自 *dest*。这通常是你想要的,因为用户永远看不到 *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)s
和 add_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¶
在一个项目的生命周期中,有些参数可能需要从命令行中移除。在移除它们之前,您应该通知用户这些参数已被弃用,并且将来会被移除。add_argument()
的 deprecated
关键字参数(默认为 False
)指定了该参数是否已被弃用并将于未来移除。对于参数,如果 deprecated
为 True
,那么当该参数被使用时,会向 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
本身,Action
类必须接受两个位置参数以及传递给ArgumentParser.add_argument()
的任何关键字参数。Action
的实例(或传递给action
参数的任何可调用对象的返回值)应定义dest
,option_strings
,default
,type
,required
,help
等属性。确保这些属性被定义的最简单方法是调用Action.__init__()
。- __call__(parser, namespace, values, option_string=None)¶
Action
实例应该是可调用的,因此子类必须重写__call__()
方法,该方法应接受四个参数parser - 包含此动作的
ArgumentParser
对象。namespace - 将由
parse_args()
返回的Namespace
对象。大多数动作使用setattr()
向该对象添加属性。values - 关联的命令行参数,并已应用任何类型转换。类型转换通过
add_argument()
的 type 关键字参数指定。option_string - 用于调用此动作的选项字符串。如果动作与位置参数关联,
option_string
参数是可选的,并且将不存在。
__call__()
方法可以执行任意操作,但通常会根据dest
和values
在namespace
上设置属性。
- format_usage()¶
Action
子类可以定义一个不带参数的format_usage()
方法,它返回一个字符串,该字符串将在打印程序用法时使用。如果未提供此方法,将使用合理的默认值。
- class argparse.BooleanOptionalAction¶
Action
的一个子类,用于处理带有肯定和否定选项的布尔标志。添加一个如--foo
这样的参数会自动创建--foo
和--no-foo
两个选项,分别存储True
和False
>>> import argparse >>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', action=argparse.BooleanOptionalAction) >>> parser.parse_args(['--no-foo']) Namespace(foo=False)
在 3.9 版本中新增。
parse_args() 方法¶
- ArgumentParser.parse_args(args=None, namespace=None)¶
将参数字符串转换为对象,并将它们赋值为命名空间的属性。返回填充好的命名空间。
之前对
add_argument()
的调用确切地决定了创建什么对象以及如何分配它们。有关详细信息,请参阅add_argument()
的文档。
选项值语法¶
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])
Namespace 对象¶
- 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'}
让
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][, dest][, required][, help][, metavar])¶
许多程序将其功能划分为多个子命令,例如,
svn
程序可以调用诸如svn checkout
、svn update
和svn commit
等子命令。当一个程序执行多个需要不同类型命令行参数的不同功能时,以这种方式划分功能可能是一个特别好的主意。ArgumentParser
支持通过add_subparsers()
方法创建此类子命令。add_subparsers()
方法通常不带参数调用,并返回一个特殊的动作对象。该对象只有一个方法,add_parser()
,它接受一个命令名和任何ArgumentParser
构造函数参数,并返回一个可以像往常一样修改的ArgumentParser
对象。参数说明
title - 帮助输出中子解析器组的标题;如果提供了 description,则默认为 “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
命令时,只有foo
和bar
属性存在,而当指定b
命令时,只有foo
和baz
属性存在。同样,当从子解析器请求帮助消息时,将只打印该特定解析器的帮助信息。帮助消息不会包括父解析器或同级解析器的消息。(然而,可以通过向
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()
方法还支持title
和description
关键字参数。当其中任何一个存在时,子解析器的命令将出现在帮助输出中它们自己的组中。例如>>> 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 参数。
在 3.14 版更改: 子解析器的 prog 不再受主解析器中自定义用法消息的影响。
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'>)
备注
如果一个参数使用了 FileType,然后后续参数失败,会报告错误但文件不会自动关闭。这也会覆盖输出文件。在这种情况下,最好等到解析器运行之后,再使用
with
语句来管理文件。在 3.4 版更改: 添加了 encodings 和 errors 参数。
自 3.14 版本起已弃用。
参数组¶
- 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()
方法返回一个参数组对象,该对象具有一个add_argument()
方法,就像常规的ArgumentParser
一样。当参数添加到组中时,解析器会像处理普通参数一样处理它,但在帮助消息中将该参数显示在单独的组中。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_default 和 conflict_handler 允许对参数组的行为进行更细粒度的控制。这些参数的含义与
ArgumentParser
构造函数中的相同,但专门应用于参数组而不是整个解析器。请注意,任何不在您用户定义组中的参数都将最终回到通常的“位置参数”和“可选参数”部分。
自 3.11 版本起已弃用,在 3.14 版本中移除: 在参数组上调用
add_argument_group()
现在会引发异常。这种嵌套从未被支持,经常无法正常工作,并且是通过继承无意中暴露出来的。自 3.14 版本起已弃用: 将 prefix_chars 传递给
add_argument_group()
现已弃用。
互斥¶
- 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 版本起已弃用,在 3.14 版本中移除: 在互斥组上调用
add_argument_group()
或add_mutually_exclusive_group()
现在会引发异常。这种嵌套从未被支持,经常无法正常工作,并且是通过继承无意中暴露出来的。
解析器默认值¶
- 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
的简要说明。如果 file 是None
,则假定为sys.stdout
。
- ArgumentParser.print_help(file=None)¶
打印帮助消息,包括程序用法和有关向
ArgumentParser
注册的参数的信息。如果 file 是None
,则假定为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 退出,如果给定,它会在退出前向
sys.stderr
打印一条 message。用户可以重写此方法以不同方式处理这些步骤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¶
在将命令行字符串转换为类型时出现问题时引发。
指南和教程