如何使用argparse在Python中编写命令行程序

来自菜鸟教程
跳转至:导航、​搜索

作者选择了 COVID-19 Relief Fund 作为 Write for DOnations 计划的一部分来接受捐赠。

介绍

Python 的 argparse 标准库模块 是一种工具,可帮助您在 Python 代码上编写命令行界面 (CLI)。 您可能已经熟悉 CLI:gitlsgrepfind 等程序都公开了允许您调用具有特定输入和选项的基础程序。 argparse 允许您使用类似于调用 gitlsgrepfind 使用命令行。 如果您想允许其他开发人员从命令行运行您的代码,您可能会发现这很有用。

在本教程中,您将使用 Python 的 argparse 标准库模块公开的一些实用程序。 您将编写接受位置和可选参数的命令行界面来控制底层程序的行为。 您还可以通过提供可以显示给使用您的 CLI 的其他开发人员的帮助文本来对 CLI 进行自我记录。

在本教程中,您将为一个跟踪虚构水族馆中鱼的程序编写命令行界面。

先决条件

为了充分利用本教程,我们建议您:

  • 熟悉 Python 3 中的编程。 您可以查看我们的 How To Code in Python 3 教程系列以了解背景知识。

编写一个接受位置参数的命令行程序

您可以使用 argparse 模块编写一个接受位置参数的命令行界面。 位置参数(与我们将在后续部分探讨的可选参数相反)通常用于指定程序所需的输入。

让我们考虑一个示例 CLI,它打印由位置 tank 参数标识的水族箱中的鱼。

要创建 CLI,请使用文本编辑器打开一个文件:

nano aquarium.py

然后,添加以下 Python 代码:

水族馆.py

import argparse

tank_to_fish = {
    "tank_a": "shark, tuna, herring",
    "tank_b": "cod, flounder",
}

parser = argparse.ArgumentParser(description="List fish in aquarium.")
parser.add_argument("tank", type=str)
args = parser.parse_args()

fish = tank_to_fish.get(args.tank, "")
print(fish)

您可以通过运行以下命令打印出 tank_a 中的鱼:

python3 aquarium.py tank_a

运行该命令后,您将收到如下输出:

Outputshark, tuna, herring

同样,如果您运行 aquarium.py 以打印出 tank_b 中的鱼:

python3 aquarium.py tank_b 

您将收到如下输出:

Outputcod, flounder

让我们分解aquarium.py中的代码。

首先,您导入 argparse 模块以使其可用于您的程序。 接下来,您创建一个字典数据结构 tank_to_fish,将鱼缸名称(如 tank_atank_b)映射到这些鱼缸中鱼的字符串描述。

您实例化 ArgumentParser 类的一个实例并将其绑定到 parser 变量。 您可以将 parser 视为配置命令行界面的主要入口点。 提供给 parserdescription 字符串(稍后您将了解)用于 aquarium.py 公开的 CLI 自动生成的帮助文本中。

在解析器上调用 add_argument 允许您添加命令行界面接受的参数。 在这种情况下,您添加一个名为 tank 的字符串类型的参数。 调用 parser.parse_args() 指示 parser 处理和验证传递给 aquarium.py 的命令行输入(例如,类似于 tank_a)。 访问 parser.parse_args() 返回的 args 允许您检索传入的 tank 参数的值,并使用它来 print 出该缸中的鱼.

至此,您已经编写了一个命令行界面并执行了打印fish 的程序。 现在您需要向其他开发人员描述您的 CLI 是如何工作的。 argparse 强烈支持帮助文本来记录您的 CLI。 接下来,您将了解有关帮助文本的更多信息。

查看帮助文本

您刚刚在上一节中编写的 aquarium.py 文件实际上不仅仅是打印特定鱼缸中的鱼。 由于您使用的是 argparse,因此 aquarium.py 公开的命令行界面将自动包含帮助和使用信息,用户可以查阅这些信息以了解有关您的程序的更多信息。

例如,如果您在命令行上提供无效参数,则会打印使用消息 aquarium.py。 尝试在命令行上使用错误的参数调用 aquarium.py,方法是运行:

python3 aquarium.py --not-a-valid-argument

如果您运行此命令,您将收到如下输出:

Outputusage: aquarium.py [-h] tank
aquarium.py: error: the following arguments are required: tank

命令行上打印的输出表明尝试运行 aquarium.py 时出错。 输出表明用户需要使用 tank 参数调用 aquarium.py。 您可能会注意到 -h 介于 [] 字符之间的其他内容。 这表示 -h 是您也可以提供的可选参数。

现在您会发现当您使用 -h 选项调用 aquarium.py 时会发生什么。 尝试通过运行以下命令在命令行上使用 -h 参数调用 aquarium.py

python3 aquarium.py -h

如果您运行此命令,您将收到如下输出:

Outputusage: aquarium.py [-h] tank

List fish in aquarium.

positional arguments:
  tank

optional arguments:
  -h, --help  show this help message and exit

您可能已经猜到了,-h 选项是“帮助”的缩写。 运行 python3 aquarium.py -h(或等效地,更长的变体 python3 aquarium.py --help)打印出帮助文本。 实际上,帮助文本是上一个示例中在您提供无效参数时输出的用法文本的较长版本。 值得注意的是,帮助文本还包括 List fish in an aquarium 的自定义 description 字符串,您在本教程前面用它实例化了 ArgumentParser

默认情况下,当您使用 argparse 编写 CLI 时,您将自动获得帮助和使用文本,您可以使用这些文本为其他开发人员记录您的 CLI。

到目前为止,您已经编写了一个接受所需位置参数的 CLI。 在下一部分中,您将向界面添加一个可选参数以扩展其功能。

添加可选参数

有时,在命令行界面中包含可选参数会很有帮助。 这些选项通常以两个短划线字符为前缀,例如 --some-option。 让我们用以下调整后的内容重写 aquarium.py,为您的 CLI 添加一个 --upper-case 选项:

水族馆.py

import argparse

tank_to_fish = {
    "tank_a": "shark, tuna, herring",
    "tank_b": "cod, flounder",
}

parser = argparse.ArgumentParser(description="List fish in aquarium.")
parser.add_argument("tank", type=str)
parser.add_argument("--upper-case", default=False, action="store_true")
args = parser.parse_args()

fish = tank_to_fish.get(args.tank, "")

if args.upper_case:
    fish = fish.upper()

print(fish)

通过运行以下命令尝试使用新的 --upper-case 参数调用 aquarium.py

python3 aquarium.py --upper-case tank_a

如果您运行此命令,您将收到如下输出:

OutputSHARK, TUNA, HERRING

tank_a 中的鱼现在以大写形式输出。 您通过在调用 parser.add_argument("--upper-case", default=False, action="store_true") 时添加一个新的 --upper-case 选项来完成此操作。 "--upper-case" 字符串是您要添加的参数的名称。

如果 CLI 的用户未提供 --upper-case 选项,则 default=False 确保其值默认设置为 Falseaction="store_true" 控制 CLI 用户提供 --upper-case 选项时发生的情况。 动作参数 支持许多 不同的可能字符串,但是 "store_true" 将值 True 存储到参数中,如果它在命令行上提供。

请注意,虽然参数是用破折号分隔的两个单词 (upper-case),但 argparse 在您调用后可将其作为 args.upper_case (带下划线分隔符)在您的代码中使用parser.parse_args()。 通常,argparse 将提供的参数中的任何破折号转换为下划线,以便在调用 parse_args() 后可以引用有效的 Python 标识符。

和以前一样,argparse 自动创建一个 --help 选项并记录您的命令行界面(包括您刚刚添加的 --upper-case 选项)。

尝试再次使用 --help 选项调用 aquarium.py 以接收更新的帮助文本:

python3 aquarium.py --help

您的输出将类似于:

Outputusage: aquarium.py [-h] [--upper-case] tank

List fish in aquarium.

positional arguments:
  tank

optional arguments:
  -h, --help    show this help message and exit
  --upper-case

argparse 自动记录了位置 tank 参数、可选的 --upper-case 选项和内置的 --help 选项。

此帮助文本很有用,但您可以使用其他信息对其进行改进,以帮助用户更好地了解他们如何调用您的程序。 您将在下一节中探索如何增强帮助文本。

向您的用户公开其他帮助文本

开发人员使用您的命令行界面提供的帮助文本来了解您的程序的功能以及他们应该如何使用它。 让我们再次修改 aquarium.py 以便它包含更好的帮助文本。 您可以通过在 add_argument 调用中指定 help 字符串来指定参数级信息:

水族馆.py

import argparse

tank_to_fish = {
    "tank_a": "shark, tuna, herring",
    "tank_b": "cod, flounder",
}

parser = argparse.ArgumentParser(description="List fish in aquarium.")
parser.add_argument("tank", type=str, help="Tank to print fish from.")
parser.add_argument(
    "--upper-case",
    default=False,
    action="store_true",
    help="Upper case the outputted fish.",
)
args = parser.parse_args()

fish = tank_to_fish[args.tank]

if args.upper_case:
    fish = fish.upper()

print(fish)

尝试再次使用 --help 选项调用 aquarium.py 以接收更新的帮助文本:

python3 aquarium.py --help

您的输出将如下所示:

Outputusage: aquarium.py [-h] [--upper-case] tank

List fish in aquarium.

positional arguments:
  tank          Tank to print fish from.

optional arguments:
  -h, --help    show this help message and exit
  --upper-case  Upper case the outputted fish.

在此最新输出中,请注意 tank 位置参数和 --upper-case 可选参数都包含自定义帮助文本。 您通过向 add_argumenthelp 部分提供字符串来提供此额外帮助文本。 (例如,parser.add_argument("tank", type=str, help="Tank to print fish from.")。)argparse 获取这些字符串并在帮助文本输出中为您呈现它们。

您可以通过让 argparse 打印出您定义的任何默认值来进一步改进您的帮助文本。

在帮助文本中显示默认值

如果您在实例化 ArgumentParser 实例时使用自定义 formatter_class,则 argparse 将在帮助文本输出中包含默认值。 尝试将 argparse.ArgumentDefaultsHelpFormatter 添加为 ArgumentParser 格式化程序类:

水族馆.py

import argparse

tank_to_fish = {
    "tank_a": "shark, tuna, herring",
    "tank_b": "cod, flounder",
}

parser = argparse.ArgumentParser(
    description="List fish in aquarium.",
    formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser.add_argument("tank", type=str, help="Tank to print fish from.")
parser.add_argument(
    "--upper-case",
    default=False,
    action="store_true",
    help="Upper case the outputted fish.",
)
args = parser.parse_args()

fish = tank_to_fish[args.tank]

if args.upper_case:
    fish = fish.upper()

print(fish)

现在,再次尝试使用 --help 选项调用 aquarium.py 以检查更新的帮助文本:

python3 aquarium.py --help

运行此命令后,您将收到如下输出:

Outputusage: aquarium.py [-h] [--upper-case] tank

List fish in aquarium.

positional arguments:
  tank          Tank to print fish from.

optional arguments:
  -h, --help    show this help message and exit
  --upper-case  Upper case the outputted fish. (default: False)

在此最新输出中,请注意 --upper-case 的文档以 --upper-case 选项 (default: False) 的默认值指示结束。 通过将 argparse.ArgumentDefaultsHelpFormatter 作为 ArgumentParserformatter_class 包含在内,argparse 会自动开始在其帮助文本中呈现默认值信息。

结论

argparse 模块是 Python 标准库的一个强大部分,它允许您为代码编写命令行界面。 本教程向您介绍了 argparse 的基础:您编写了一个接受位置参数和可选参数的命令行界面,并向用户公开了帮助文本。

argparse 支持更多功能,您可以使用这些功能编写具有复杂输入和验证集的命令行程序。 从这里,您可以使用 argparse 模块的文档 了解有关其他可用类和实用程序的更多信息。