前言

argparse 模块可以让人轻松编写用户友好的命令行接口。 程序定义它需要哪些参数,argparse 将会知道如何从 sys.argv 解析它们。 argparse 模块还能自动生成帮助和用法消息文本。 该模块还会在用户向程序传入无效参数时发出错误消息。

Operating System: Ubuntu 22.04.4 LTS

参考文档

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

核心功能

argparse 模块对命令行接口的支持是围绕 argparse.ArgumentParser 的实例建立的。 它是一个用于参数规格说明的容器并包含多个全面应用解析器的选项:

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

ArgumentParser.add_argument() 方法将单个参数规格说明关联到解析器。 它支持位置参数,接受各种值的选项,以及各种启用/禁用旗标:

1
2
3
4
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 对象:

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

有关 add_argument() 的快速链接

名称 描述
action 指明应当如何处理一个参数 ‘store’, ‘store_const’, ‘store_true’, ‘append’, ‘append_const’, ‘count’, ‘help’, ‘version’
choices 将值限制为指定的可选项集合 [‘foo’, ‘bar’], range(1, 10) 或 Container 实例
const 存储一个常量值
default 当未提供某个参数时要使用的默认值 默认为 None
dest 指定要在结果命名空间中使用的属性名称
help 某个参数的帮助消息
metavar 要在帮助中显示的参数替代显示名称
nargs 参数可被使用的次数 int, ‘?’, ‘*’ 或 ‘+’
required 指明某个参数是必需的还是可选的 True 或 False
type 自动将参数转换为给定的类型 int, float, argparse.FileType(‘w’) 或可调用函数

示例

以下代码是一个 Python 程序,它获取一个整数列表并计算总和或者最大值:

1
2
3
4
5
6
7
8
9
10
11
import argparse

parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('integers', metavar='N', type=int, nargs='+',
help='an integer for the accumulator')
parser.add_argument('--sum', dest='accumulate', action='store_const',
const=sum, default=max,
help='sum the integers (default: find the max)')

args = parser.parse_args()
print(args.accumulate(args.integers))

假定上面的 Python 代码保存在名为 prog.py 的文件中,它可以在命令行中运行并提供有用的帮助消息:

1
2
3
4
5
6
7
8
9
10
11
$ python prog.py -h
usage: prog.py [-h] [--sum] N [N ...]

Process some integers.

positional arguments:
N an integer for the accumulator

options:
-h, --help show this help message and exit
--sum sum the integers (default: find the max)

当使用适当的参数运行时,它会输出命令行传入整数的总和或者最大值:

1
2
3
4
5
$ python prog.py 1 2 3 4
4

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

如果传入了无效的参数,将显示一个错误消息:

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

ArgumentParser 对象

description

大多数对 ArgumentParser 构造方法的调用都会使用 description= 关键字参数。 这个参数简要描述这个程序做什么以及怎么做。 在帮助消息中,这个描述会显示在命令行用法字符串和各种参数的帮助消息之间:

1
2
3
4
5
6
7
8
>>> parser = argparse.ArgumentParser(description='A foo that bars')
>>> parser.print_help()
usage: argparse.py [-h]

A foo that bars

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

在默认情况下,description 将被换行以便适应给定的空间。如果想改变这种行为,见 formatter_class 参数。

parents

有些时候,少数解析器会使用同一系列参数。 单个解析器能够通过提供 parents= 参数给 ArgumentParser 而使用相同的参数而不是重复这些参数的定义。parents= 参数使用 ArgumentParser 对象的列表,从它们那里收集所有的位置和可选的行为,然后将这写行为加到正在构建的 ArgumentParser 对象。

1
2
3
4
5
6
7
8
9
10
11
12
>>> 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 . 否则, ArgumentParse 将会看到两个 -h/–help 选项(一个在父参数中一个在子参数中)并且产生一个错误。

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

add_argument() 方法

name or flags

可以这样创建可选参数:

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

而位置参数可以这么创建:

1
>>> parser.add_argument('bar')

choices

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

1
2
3
4
5
6
7
8
>>> 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 相匹配:

1
2
3
4
5
6
7
>>> 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 对象、tuple 对象以及自定义序列都是受支持的。

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

已格式化的选项会覆盖默认的 metavar,该值一般是派生自 dest。 这通常就是你所需要的,因为用户永远不会看到 dest 形参。 如果不想要这样的显示(或许因为有很多选择),只需指定一个显式的 metavar。

结语

第一百六十九篇博文写完,开心!!!!

今天,也是充满希望的一天。