python 标准库 argparse 命令行选项
每日一词:
eternity n 永恒 不朽
近义词:
invariability n 恒久不变的东西
perpetuity n 永久 永恒
timelessness n 永恒
permanence n 永久 持久
everlasting adj永恒的
源码
源代码: Lib/argparse.py
argparse
模块可以让人轻松编写用户友好的命令行接口。程序定义它需要的参数,然后 argparse
将弄清如何从 sys.argv
解析出那些参数。 argparse
模块还会自动生成帮助和使用手册,并在用户给程序传入无效参数时报出错误信息。
示例
以下代码是一个 Python 程序,它获取一个整数列表并计算总和或者最大值:
1 | import argparse |
假设上面的 Python 代码保存在名为 prog.py
的文件中,它可以在命令行运行并提供有用的帮助消息:
1 | $ python prog.py -h |
当使用适当的参数运行时,它会输出命令行传入整数的总和或者最大值:
1 | $ python prog.py 1 2 3 4 |
如果传入无效参数,则会报出错误:
1 | $ python prog.py a b c |
以下部分将引导你完成这个示例。
创建一个解析器
使用 argparse
的第一步是创建一个 ArgumentParser
对象:
1 | 'Process some integers.') parser = argparse.ArgumentParser(description= |
ArgumentParser
对象包含将命令行解析成 Python 数据类型所需的全部信息。
添加参数
给一个 ArgumentParser
添加程序参数信息是通过调用 add_argument()
方法完成的。通常,这些调用指定 ArgumentParser
如何获取命令行字符串并将其转换为对象。这些信息在 parse_args()
调用时被存储和使用。例如:
1 | 'integers', metavar='N', type=int, nargs='+', parser.add_argument( |
稍后,调用 parse_args()
将返回一个具有 integers
和 accumulate
两个属性的对象。integers
属性将是一个包含一个或多个整数的列表,而 accumulate
属性当命令行中指定了 --sum
参数时将是 sum()
函数,否则则是 max()
函数。
解析参数
ArgumentParser
通过 parse_args()
方法解析参数。它将检查命令行,把每个参数转换为适当的类型然后调用相应的操作。在大多数情况下,这意味着一个简单的 Namespace
对象将从命令行参数中解析出的属性构建:
1 | '--sum', '7', '-1', '42']) parser.parse_args([ |
在脚本中,通常 parse_args()
会被不带参数调用,而 ArgumentParser
将自动从 sys.argv
中确定命令行参数。
ArgumentParser 对象
创建一个新的 ArgumentParser
对象。所有的参数都应当作为关键字参数传入。每个参数在下面都有它更详细的描述,但简而言之,它们是:
prog - 程序的名称(默认:
sys.argv[0]
)usage - 描述程序用途的字符串(默认值:从添加到解析器的参数生成)
description - 在参数帮助文档之前显示的文本(默认值:无)
epilog - 在参数帮助文档之后显示的文本(默认值:无)
parents - 一个
ArgumentParser
对象的列表,它们的参数也应包含在内formatter_class - 用于自定义帮助文档输出格式的类
prefix_chars - 可选参数的前缀字符集合(默认值:’-‘)
fromfile_prefix_chars - 当需要从文件中读取其他参数时,用于标识文件名的前缀字符集合(默认值:
None
)argument_default - 参数的全局默认值(默认值:
None
)conflict_handler - 解决冲突选项的策略(通常是不必要的)
add_help - 为解析器添加一个
-h/--help
选项(默认值:True
)allow_abbrev - 如果缩写是无歧义的,则允许缩写长选项 (默认值:
True
)
以下部分描述这些参数如何使用。
prog
默认情况下,ArgumentParser
对象使用 sys.argv[0]
来确定如何在帮助消息中显示程序名称。这一默认值几乎总是可取的,因为它将使帮助消息与从命令行调用此程序的方式相匹配。例如,对于有如下代码的名为 myprogram.py
的文件:
1 | import argparse |
该程序的帮助信息将显示 myprogram.py
作为程序名称(无论程序从何处被调用):
1 | $ python myprogram.py --help |
要更改这样的默认行为,可以使用 prog=
参数为 ArgumentParser
提供另一个值:
1 | 'myprogram') parser = argparse.ArgumentParser(prog= |
需要注意的是,无论是从 sys.argv[0]
或是从 prog=
参数确定的程序名称,都可以在帮助消息里通过 %(prog)s
格式串来引用。
1 | 'myprogram') parser = argparse.ArgumentParser(prog= |
usage
默认情况下,ArgumentParser
根据它包含的参数来构建用法消息:
1 | 'PROG') parser = argparse.ArgumentParser(prog= |
可以通过 usage=
关键字参数覆盖这一默认消息:
1 | 'PROG', usage='%(prog)s [options]') parser = argparse.ArgumentParser(prog= |
在用法消息中可以使用 %(prog)s
格式说明符来填入程序名称。
description
大多数对 ArgumentParser
构造方法的调用都会使用 description=
关键字参数。这个参数简要描述这个程度做什么以及怎么做。在帮助消息中,这个描述会显示在命令行用法字符串和各种参数的帮助消息之间:
1 | 'A foo that bars') parser = argparse.ArgumentParser(description= |
在默认情况下,description 将被换行以便适应给定的空间。如果想改变这种行为,见 formatter_class 参数。
epilog
一些程序喜欢在 description 参数后显示额外的对程序的描述。这种文字能够通过给 ArgumentParser
:: 提供 epilog=
参数而被指定。
1 | parser = argparse.ArgumentParser( |
和 description 参数一样,epilog=
text 在默认情况下会换行,但是这种行为能够被调整通过提供 formatter_class 参数给 ArgumentParse
.
parents
有些时候,少数解析器会使用同一系列参数。 单个解析器能够通过提供 parents=
参数给 ArgumentParser
而使用相同的参数而不是重复这些参数的定义。parents=
参数使用 ArgumentParser
对象的列表,从它们那里收集所有的位置和可选的行为,然后将这写行为加到正在构建的 ArgumentParser
对象。
1 | False) parent_parser = argparse.ArgumentParser(add_help= |
请注意大多数父解析器会指定 add_help=False
. 否则, ArgumentParse
将会看到两个 -h/--help
选项(一个在父参数中一个在子参数中)并且产生一个错误。
你在传parents=给那些解析器时必须完全初始化它们。如果你在子解析器之后改变父解析器是,这些改变不会反映在子解析器上。
formatter_class
ArgumentParser
对象允许通过指定备用格式化类来自定义帮助格式。目前,有四种这样的类。
- class
argparse.RawDescriptionHelpFormatter
- class
argparse.RawTextHelpFormatter
- class
argparse.ArgumentDefaultsHelpFormatter
class
argparse.MetavarTypeHelpFormatter
RawDescriptionHelpFormatter
和RawTextHelpFormatter
在正文的描述和展示上给与了更多的控制。ArgumentParser
对象会将 description 和 epilog 的文字在命令行中自动换行。
1 | parser = argparse.ArgumentParser( |
传 RawDescriptionHelpFormatter
给 formatter_class=
表示 description 和 epilog 已经被正确的格式化了,不能在命令行中被自动换行:
1 | parser = argparse.ArgumentParser( |
RawTextHelpFormatter
保留所有种类文字的空格,包括参数的描述。然而,多重的新行会被替换成一行。如果你想保留多重的空白行,可以在新行之间加空格。
ArgumentDefaultsHelpFormatter
自动添加默认的值的信息到每一个帮助信息的参数中:
1 | parser = argparse.ArgumentParser( |
MetavarTypeHelpFormatter
为它的值在每一个参数中使用 type 的参数名当作它的显示名(而不是使用通常的格式 dest ):
1 | parser = argparse.ArgumentParser( |
prefix_chars
许多命令行会使用 -
当作前缀,比如 -f/--foo
。如果解析器需要支持不同的或者额外的字符,比如像 +f
或者 /foo
的选项,可以在参数解析构建器中使用 prefix_chars=
参数。
1 | 'PROG', prefix_chars='-+') parser = argparse.ArgumentParser(prog= |
The prefix_chars=
参数默认使用 '-'
. 支持一系列字符,但是不包括 -
,这样会产生不被允许的 -f/--foo
选项。
fromfile_prefix_chars
有些时候,先举个例子,当处理一个特别长的参数列表的时候,把它存入一个文件中而不是在命令行打出来会很有意义。如果 fromfile_prefix_chars=
参数提供给 ArgumentParser
构造函数,之后所有类型的字符的参数都会被当成文件处理,并且会被文件包含的参数替代。举个栗子:
1 | with open('args.txt', 'w') as fp: |
从文件读取的参数在默认情况下必须一个一行(但是可参见 convert_arg_line_to_args()
)并且它们被视为与命令行上的原始文件引用参数位于同一位置。所以在以上例子中,['-f', 'foo', '@args.txt']
的表示和 ['-f', 'foo', '-f', 'bar']
的表示相同。
fromfile_prefix_chars=
参数默认为 None
,意味着参数不会被当作文件对待。
argument_default
一般情况下,参数默认会通过设置一个默认到 add_argument()
或者调用带一组指定键值对的 ArgumentParser.set_defaults()
方法。但是有些时候,为参数指定一个普遍适用的解析器会更有用。这能够通过传输 argument_default=
关键词参数给 ArgumentParser
来完成。举个栗子,要全局禁止在 parse_args()
中创建属性,我们提供 argument_default=SUPPRESS
:
1 | parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS) |
allow_abbrev
正常情况下,当你向 ArgumentParser
的 parse_args()
方法传入一个参数列表时,它会 recognizes abbreviations。
这个特性可以设置 allow_abbrev
为 False
来关闭:
1 | 'PROG', allow_abbrev=False) parser = argparse.ArgumentParser(prog= |
conflict_handler
ArgumentParser
对象不允许在相同选项字符串下有两种行为。默认情况下, ArgumentParser
对象会产生一个异常如果去创建一个正在使用的选项字符串参数。
1 | 'PROG') parser = argparse.ArgumentParser(prog= |
有些时候(例如:使用 parents),重写旧的有相同选项字符串的参数会更有用。为了产生这种行为, 'resolve'
值可以提供给 ArgumentParser
的 conflict_handler=
参数:
1 | 'PROG', conflict_handler='resolve') parser = argparse.ArgumentParser(prog= |
注意 ArgumentParser
对象只能移除一个行为如果它所有的选项字符串都被重写。所以,在上面的例子中,旧的 -f/--foo
行为 回合 -f
行为保持一样, 因为只有 --foo
选项字符串被重写。
add_help
默认情况下,ArgumentParser 对象添加一个简单的显示解析器帮助信息的选项。举个栗子,考虑一个名为 myprogram.py
的文件包含如下代码:
1 | import argparse |
如果 -h
or --help
在命令行中被提供, 参数解析器帮助信息会打印:
1 | $ python myprogram.py --help |
有时候可能会需要关闭额外的帮助信息。这可以通过在 ArgumentParser
中设置 add_help=
参数为 False
来实现。
1 | 'PROG', add_help=False) parser = argparse.ArgumentParser(prog= |
帮助选项一般为 -h/--help
。如果 prefix_chars=
被指定并且没有包含 -
字符,在这种情况下, -h
--help
不是有效的选项。此时, prefix_chars
的第一个字符将用作帮助选项的前缀。
1 | 'PROG', prefix_chars='+/') parser = argparse.ArgumentParser(prog= |
add_argument() 方法
ArgumentParser.add_argument
(name or flags…[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest])
定义单个的命令行参数应当如何解析。每个形参都在下面有它自己更多的描述,长话短说有:
- name or flags - 一个命名或者一个选项字符串的列表,例如
foo
或-f, --foo
。 - action - 当参数在命令行中出现时使用的动作基本类型。
- nargs - 命令行参数应当消耗的数目。
- const - 被一些 action 和 nargs 选择所需求的常数。
- default - 当参数未在命令行中出现时使用的值。
- type - 命令行参数应当被转换成的类型。
- choices - 可用的参数的容器。
- required - 此命令行选项是否可省略 (仅选项可用)。
- help - 一个此选项作用的简单描述。
- metavar - 在使用方法消息中使用的参数值示例。
dest - 被添加到
parse_args()
所返回对象上的属性名。以下部分描述这些参数如何使用。
name or flags
add_argument()
方法必须知道它是否是一个选项,例如 -f
或 --foo
,或是一个位置参数,例如一组文件名。第一个传递给 add_argument()
的参数必须是一系列 flags 或者是一个简单的参数名。例如,可以选项可以被这样创建:
1 | '-f', '--foo') parser.add_argument( |
而位置参数可以这么创建:
1 | 'bar') parser.add_argument( |
当 parse_args()
被调用,选项会以 -
前缀识别,剩下的参数则会被假定为位置参数:
1 | 'PROG') parser = argparse.ArgumentParser(prog= |
action
ArgumentParser
对象将命令行参数与动作相关联。这些动作可以做与它们相关联的命令行参数的任何事,尽管大多数动作只是简单的向 parse_args()
返回的对象上添加属性。action
命名参数指定了这个命令行参数应当如何处理。供应的动作有:
'store'
- 存储参数的值。这是默认的动作。例如:1
2
3
4parser = argparse.ArgumentParser()
'--foo') parser.add_argument(
'--foo 1'.split()) parser.parse_args(
Namespace(foo='1')'store_const'
- 存储被 const 命名参数指定的值。'store_const'
动作通常用在选项中来指定一些标志。例如:1
2
3
4parser = argparse.ArgumentParser()
'--foo', action='store_const', const=42) parser.add_argument(
'--foo']) parser.parse_args([
Namespace(foo=42)'store_true'
and'store_false'
- 这些是'store_const'
分别用作存储True
和False
值的特殊用例。另外,它们的默认值分别为False
和True
。例如:1
2
3
4
5
6parser = argparse.ArgumentParser()
'--foo', action='store_true') parser.add_argument(
'--bar', action='store_false') parser.add_argument(
'--baz', action='store_false') parser.add_argument(
'--foo --bar'.split()) parser.parse_args(
Namespace(foo=True, bar=False, baz=True)'append'
- 存储一个列表,并且将每个参数值追加到列表中。在允许多次使用选项时很有用。例如:1
2
3
4parser = argparse.ArgumentParser()
'--foo', action='append') parser.add_argument(
'--foo 1 --foo 2'.split()) parser.parse_args(
Namespace(foo=['1', '2'])'append_const'
- 这存储一个列表,并将 const 命名参数指定的值追加到列表中。(注意 const 命名参数默认为None
。)’append_const’ 动作一般在多个参数需要在同一列表中存储常数时会有用。例如:1
2
3
4
5parser = argparse.ArgumentParser()
'--str', dest='types', action='append_const', const=str) parser.add_argument(
'--int', dest='types', action='append_const', const=int) parser.add_argument(
'--str --int'.split()) parser.parse_args(
Namespace(types=[<class 'str'>, <class 'int'>])'count'
- 计算一个关键字参数出现的数目或次数。例如,对于一个增长的详情等级来说有用:1
2
3
4parser = argparse.ArgumentParser()
'--verbose', '-v', action='count', default=0) parser.add_argument(
'-vvv']) parser.parse_args([
Namespace(verbose=3)Note, the default will be
None
unless explicitly set to 0.'help'
- 打印所有当前解析器中的选项和参数的完整帮助信息,然后退出。默认情况下,一个 help 动作会被自动加入解析器。关于输出是如何创建的,参与ArgumentParser
。'version'
- 期望有一个version=
命名参数在add_argument()
调用中,并打印版本信息并在调用后退出:1
2
3
4
5import argparse
'PROG') parser = argparse.ArgumentParser(prog=
'--version', action='version', version='%(prog)s 2.0') parser.add_argument(
'--version']) parser.parse_args([
PROG 2.0'extend'
- This stores a list, and extends each argument value to the list. Example usage:1
2
3
4parser = argparse.ArgumentParser()
"--foo", action="extend", nargs="+", type=str) parser.add_argument(
"--foo", "f1", "--foo", "f2", "f3", "f4"]) parser.parse_args([
Namespace(foo=['f1', 'f2', 'f3', 'f4'])
3.8 新版功能.
您还可以通过传递 Action 子类或实现相同接口的其他对象来指定任意操作。建议的方法是扩展 Action
,覆盖 __call__
方法和可选的 __init__
方法。
一个自定义动作的例子:
1 | class FooAction(argparse.Action): |
nargs
ArgumentParser 对象通常关联一个单独的命令行参数到一个单独的被执行的动作。 nargs
命名参数关联不同数目的命令行参数到单一动作。支持的值有:
N
(一个整数)。命令行中的N
个参数会被聚集到一个列表中。 例如:>>>
1
2
3
4
5>>> 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 值。一些说用用例:1
2
3
4
5
6
7
8
9parser = argparse.ArgumentParser()
'--foo', nargs='?', const='c', default='d') parser.add_argument(
'bar', nargs='?', default='d') parser.add_argument(
'XX', '--foo', 'YY']) parser.parse_args([
Namespace(bar='XX', foo='YY')
'XX', '--foo']) parser.parse_args([
Namespace(bar='XX', foo='c')
parser.parse_args([])
Namespace(bar='d', foo='d')nargs='?'
的一个更普遍用法是允许可选的输入或输出文件:1
2
3
4
5
6
7
8
9
10
11parser = argparse.ArgumentParser()
'infile', nargs='?', type=argparse.FileType('r'), parser.add_argument(
default=sys.stdin)
'outfile', nargs='?', type=argparse.FileType('w'), parser.add_argument(
default=sys.stdout)
'input.txt', 'output.txt']) parser.parse_args([
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='*'
来实现多个位置参数通常没有意义,但是多个选项是可能的。例如:1
2
3
4
5
6parser = argparse.ArgumentParser()
'--foo', nargs='*') parser.add_argument(
'--bar', nargs='*') parser.add_argument(
'baz', nargs='*') parser.add_argument(
'a b --foo x y --bar 1 2'.split()) parser.parse_args(
Namespace(bar=['1', '2'], baz=['a', 'b'], foo=['x', 'y'])'+'
。和'*'
类似,所有当前命令行参数被聚集到一个列表中。另外,当前没有至少一个命令行参数时会产生一个错误信息。例如:1
2
3
4
5
6
7'PROG') parser = argparse.ArgumentParser(prog=
'foo', nargs='+') parser.add_argument(
'a', 'b']) parser.parse_args([
Namespace(foo=['a', 'b'])
parser.parse_args([])
usage: PROG [-h] foo [foo ...]
PROG: error: the following arguments are required: fooargarse.REMAINDER
。所有剩余的命令行参数被聚集到一个列表中。这通常在从一个命令行功能传递参数到另一个命令行功能中时有用:>>>
1
2
3
4
5
6'PROG') parser = argparse.ArgumentParser(prog=
'--foo') parser.add_argument(
'command') parser.add_argument(
'args', nargs=argparse.REMAINDER) parser.add_argument(
'--foo B cmd --arg1 XX ZZ'.split())) print(parser.parse_args(
Namespace(args=['--arg1', 'XX', 'ZZ'], command='cmd', foo='B')
如果不提供 nargs
命名参数,则消耗参数的数目将被 action 决定。通常这意味着单一项目(非列表)消耗单一命令行参数。
const
add_argument()
的const 参数用于保存不从命令行中读取但被各种 ArgumentParser
动作需求的常数值。最常用的两例为:
- 当
add_argument()
通过action='store_const'
或action='append_const
调用时。这些动作将const
值添加到parse_args()
返回的对象的属性中。在 action 的描述中查看案例。 - 当
add_argument()
通过选项(例如-f
或--foo
)调用并且nargs='?'
时。这会创建一个可以跟随零个或一个命令行参数的选项。当解析命令行时,如果选项后没有参数,则将用const
代替。在 nargs 描述中查看案例。
对 'store_const'
和 'append_const'
动作, const
命名参数必须给出。对其他动作,默认为 None
。
default
所有选项和一些位置参数可能在命令行中被忽略。add_argument()
的命名参数 default
,默认值为 None
,指定了在命令行参数未出现时应当使用的值。对于选项, default
值在选项未在命令行中出现时使用:
1 | parser = argparse.ArgumentParser() |
如果 default
值是一个字符串,解析器解析此值就像一个命令行参数。特别是,在将属性设置在 Namespace
的返回值之前,解析器应用任何提供的 type 转换参数。否则解析器使用原值:
1 | parser = argparse.ArgumentParser() |
对于 nargs 等于 ?
或 *
的位置参数, default
值在没有命令行参数出现时使用。
1 | parser = argparse.ArgumentParser() |
提供 default=argparse.SUPPRESS
导致命令行参数未出现时没有属性被添加:
1 | parser = argparse.ArgumentParser() |
type
默认情况下,ArgumentParser
对象将命令行参数当作简单字符串读入。然而,命令行字符串经常需要被当作其它的类型,比如 float
或者 int
。add_argument()
的 type
关键词参数允许任何的类型检查和类型转换。一般的内建类型和函数可以直接被 type
参数使用。
1 | parser = argparse.ArgumentParser() |
当 type
参数被应用到默认参数时,请参考 default 参数的部分。
type 也可以指定写入文件,通过指定 mode=
, bufsize=
, encoding=
and errors=
等参数调用open
方法打开文件。举个栗子,设定FileType('w')
参数可以设定创建一个可写的文件。
1 | parser = argparse.ArgumentParser() |
type=
can take any callable that takes a single string argument and returns the converted value:
1 | def perfect_square(string): |
choices 关键词参数可能会使类型检查者更方便的检查一个范围的值。
1 | 'PROG') parser = argparse.ArgumentParser(prog= |
choices
一些命令行参数从一组受限制的值中获取。这些可以通过容器对象,借助choice
关键字参数传递给 add_argument()
来处理,分析命令行时,将检查参数值,如果参数不是可接受的值之一,将显示错误消息:
1 | >>> parser = argparse.ArgumentParser(prog='game.py') |
需要注意的是 类型转换执行后执行检查, choice
容器必须匹配这些类型声明。
1 | 'doors.py') parser = argparse.ArgumentParser(prog= |
任何容器可以通过 choice
值来传递参数,例如 list 和 set 对象,亦或者是支持的自定义容器。
required
通常情况下,可以通过 -f
and --bar
参数声明可选参数,这些参数可以在命令行执行的时候被忽略。如果想把这些单数设置成必须参数,则需要在add_argument()
参数中将 require参数设置成True
1 | >>> parser = argparse.ArgumentParser() |
就像上述例子显示的情况一样。如果一个功能被标识为必须的,在命令行执行的时候,会不断报错。
必须参数被认为不是一个好习惯。用户期望功能都是可选的,避免成为必须参数