argparse 传参之 add_argument() 方法
沉舟侧畔千帆过,病树前头万木春

1引言
这节讲讲 argparse
怎么添加参数以及相关的选项介绍。
2参数一览
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() 所返回对象上的属性名。
以下部分描述这些参数如何使用。
3参数详解
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
action
ArgumentParser 对象将命令行参数与动作相关联。这些动作可以做与它们相关联的命令行参数的任何事,尽管大多数动作只是简单的向 parse_args() 返回的对象上添加属性。action 命名参数指定了这个命令行参数应当如何处理。供应的动作有:
-
'store'
– 存储参数的值。这是默认的动作。例如:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> parser.parse_args('--foo 1'.split())
Namespace(foo='1')
-
'store_const'
– 该函数存储关键字 const 参数指定的值;注意 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'
and'store_false'
– 这些是 ‘store_const’ 分别用作存储 True 和 False 值的特殊用例。另外,它们的默认值分别为 False 和 True。例如:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='store_true')
>>> parser.add_argument('--bar', action='store_false')
>>> parser.add_argument('--baz', action='store_false')
>>> parser.parse_args('--foo --bar'.split())
Namespace(foo=True, bar=False, baz=True)
-
'append'
– 存储一个列表,并且将每个参数值追加到列表中。在允许多次使用选项时很有用。例如:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='append')
>>> parser.parse_args('--foo 1 --foo 2'.split())
Namespace(foo=['1', '2'])
-
'append_const'
– 这存储了一个列表,并将 const 关键字参数指定的值附加到列表;请注意,const 关键字参数默认为 None。当多个参数需要将常量存储到同一列表时,“append_const”操作通常很有用。例如:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--str', dest='types', action='append_const', const=str)
>>> parser.add_argument('--int', dest='types', action='append_const', const=int)
>>> parser.parse_args('--str --int'.split())
Namespace(types=[<class 'str'>, <class 'int'>])
-
'count'
– 计算一个关键字参数出现的数目或次数。例如,对于一个增长的详情等级来说有用:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--verbose', '-v', action='count', default=0)
>>> parser.parse_args(['-vvv'])
Namespace(verbose=3)
请注意,default 将为 None,除非显式地设为 0。
-
'version'
– 期望有一个 version= 命名参数在 add_argument() 调用中,并打印版本信息并在调用后退出:
>>> import argparse
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--version', action='version', version='%(prog)s 2.0')
>>> parser.parse_args(['--version'])
PROG 2.0
-
'extend'
– 这会存储一个列表,并将每个参数值加入到列表中。示例用法:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument("--foo", action="extend", nargs="+", type=str)
>>> parser.parse_args(["--foo", "f1", "--foo", "f2", "f3", "f4"])
Namespace(foo=['f1', 'f2', 'f3', 'f4'])
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=’*’ 来实现多个位置参数通常没有意义,但是多个选项是可能的。例如:
>>> 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 决定。通常这意味着单一项目(非列表)消耗单一命令行参数。
const
常数,通常与 action='store_const'
和 action='append_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 值是一个字符串,解析器解析此值就像一个命令行参数。特别是,在将属性设置在 Namespace 的返回值之前,解析器应用任何提供的 type 转换参数。否则解析器使用原值:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--length', default='10', type=int)
>>> parser.add_argument('--width', default=10.5, type=int)
>>> parser.parse_args()
Namespace(length=10, width=10.5)
对于 nargs 等于 ? 或 * 的位置参数, default 值在没有命令行参数出现时使用:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('foo', nargs='?', default=42)
>>> parser.parse_args(['a'])
Namespace(foo='a')
>>> parser.parse_args([])
Namespace(foo=42)
提供 default=argparse.SUPPRESS
导致命令行参数未出现时没有属性被添加:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default=argparse.SUPPRESS)
>>> parser.parse_args([])
Namespace()
>>> parser.parse_args(['--foo', '1'])
Namespace(foo='1')
type
默认情况下,解析器会将命令行参数当作简单字符串读入。然而,命令行字符串经常应当被解读为其他类型,例如 float 或 int。add_argument() 的 type 关键字允许执行任何必要的类型检查和类型转换。
如果 type 关键字使用了 default 关键字,则类型转换器仅会在默认值为字符串时被应用。
传给 type 的参数可以是任何接受单个字符串的可调用对象。如果函数引发了 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('source_file', type=open)
parser.add_argument('dest_file', type=argparse.FileType('w', encoding='latin-1'))
parser.add_argument('datapath', type=pathlib.Path)
不建议将 bool() 函数用作类型转换器。它所做的只是将空字符串转为 False 而将非空字符串转为 True。这通常不是用户所想要的。
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 容器包含的内容会在执行任意 type 转换之后被检查,因此 choices 容器中对象的类型应当与指定的 type 相匹配:
>>> parser = argparse.ArgumentParser(prog='doors.py')
>>> parser.add_argument('door', type=int, choices=range(1, 4))
>>> print(parser.parse_args(['3']))
Namespace(door=3)
>>> parser.parse_args(['4'])
usage: doors.py [-h] {1,2,3}
doors.py: error: argument door: invalid choice: 4 (choose from 1, 2, 3)
任何容器都可作为 choices 值传入,因此 list 对象,set 对象以及自定义容器都是受支持的。
已格式化的选项会覆盖默认的 metavar,该值一般是派生自 dest。这通常就是你所需要的,因为用户永远不会看到 dest 形参。如果不想要这样的显示(或许因为有很多选择),只需指定一个显式的 metavar。
required
通常,argparse 模块会认为 -f 和 –bar 等旗标是指明 可选的 参数,它们总是可以在命令行中被忽略。要让一个选项成为 必需的,则可以将 True 作为 required= 关键字参数传给 add_argument():
>>> 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 描述将随每个参数一同显示:
>>> parser = argparse.ArgumentParser(prog='frobble')
>>> parser.add_argument('--foo', action='store_true',
... help='foo the bars before frobbling')
>>> parser.add_argument('bar', nargs='+',
... help='one of the bars to be frobbled')
>>> parser.parse_args(['-h'])
usage: frobble [-h] [--foo] bar [bar ...]
positional arguments:
bar one of the bars to be frobbled
options:
-h, --help show this help message and exit
--foo foo the bars before frobbling
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
metavar
当 ArgumentParser 生成帮助消息时,它需要用某种方式来引用每个预期的参数。默认情况下,ArgumentParser 对象使用 dest 值作为每个对象的 “name”。默认情况下,对于位置参数动作,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')
4结尾
下一节介绍 parse_args()
方法。敬请期待!

欢迎加入生信交流群。加我微信我也拉你进 微信群聊 老俊俊生信交流群
哦,数据代码已上传至QQ群,欢迎加入下载。
群二维码:

老俊俊微信:
知识星球:
所以今天你学习了吗?
欢迎小伙伴留言评论!
今天的分享就到这里了,敬请期待下一篇!
最后欢迎大家分享转发,您的点赞是对我的鼓励和肯定!
如果觉得对您帮助很大,赏杯快乐水喝喝吧!
往期回顾
◀argparse 传参之 ArgumentParser 对象
◀组会文献分享 –– miR455–3p 影响 HSF1 基因的 m6A 修饰参与结直肠癌的发生发展
◀...
请关注“恒诺新知”微信公众号,感谢“R语言“,”数据那些事儿“,”老俊俊的生信笔记“,”冷🈚️思“,“珞珈R”,“生信星球”的支持!