想要编写更专业、更简洁的代码吗?使用 Python argparse 模块。本文将向您展示如何使用 argparse 在 Python 中构建命令行界面。

在 Python 中,argparse argparse 是可以帮助您编写更专业、更好看的 Python 代码的模块之一。这是因为 argparse 它可以轻松编写用户友好的命令行界面。在本文结束时,您将获得有关 argparse 模块的扎实知识 - 您甚至可以将本文用作 Python argparse 备忘单。

你准备好了吗?让我们开始吧!

从命令行 OpenCV 加载图像

OpenCV 是一个非常流行的计算机视觉库。它执行各种任务来处理图像、检测对象等。在这里,我们将使用它来提供一些使用 Python 模块从命令行运行脚本的视觉示例 argparse

您可以 OpenCV 直接使用以下命令 pip

pip install OpenCV-python

由于我们不需要安装 Python argparse ,所以我们可以直接开始。

按照本指南操作时,您可以随意选择自己喜欢的图像。我从 Unsplash ,并将其重命名, 001.jpg 以便于操作。如果您更喜欢使用 Python 直接下载文件,可以 在此处 。(顺便说一句,如果您想了解如何轻松地做到这一点,请查看我关于 在 Python 中重命名文件 的文章。)

我们将构建的命令行界面

首先,让我们从脚本开始,该脚本用于在 OpenCV 中加载图像或围绕 x 轴 。我们希望从命令行运行它。简而言之,我们的脚本将调用 imread() imshow() 方法来 OpenCV 读取和显示图像。

我们还将添加选项,以调用 flip() 方法来 OpenCV 垂直翻转图像。这将通过一个语句完成 if-else 。如果我使用该 --flip 参数,则输出将是翻转的图像;否则,它将仅显示图像。

以下代码的 display_img_opencv.py 文件

import cv2
import argparse

# Construct the argument parser and parse the arguments
arg_desc = '''\
        Let's load an image from the command line!
        --------------------------------
            This program loads an image
            with OpenCV and Python argparse!
        '''
parser = argparse.ArgumentParser(formatter_class = argparse.RawDescriptionHelpFormatter,
                                    description= arg_desc)

parser.add_argument("-i", "--image", metavar="IMAGE", help = "Path to your input image")
parser.add_argument("-f", "--flip", metavar="IMAGE_FLIP", help = "Path to your input image")
args = vars(parser.parse_args())


if args["flip"]:
    # Flip the image vertically
    print("[INFO] flipping image vertically...")
    flipped = cv2.imread(args["flip"])
    flip_img = cv2.flip(flipped, 0)
   
    # Display the flipped image and press any key to stop
    cv2.imshow("Flipped vertically", flip_img)
   
else:
    # Load the image with "cv2.imread"
    image = cv2.imread(args["image"])
    # Display the original image
    cv2.imshow("Image", image)

cv2.waitKey(0)

然后,我们可以用以下命令运行脚本:

python display_img_opencv.py --image 001.jpg

结果如下:

A Guide to the Python argparse Module

或者我们可以使用以下命令行指令垂直翻转图像:

python display_img_opencv.py --flip 001.jpg

因此,我们的初始图像已绕 x 轴 .

A Guide to the Python argparse Module

您可以按任意键停止脚本。请随意用您自己的图像尝试一下。

现在,让我们解释如何使用 Python 模块构建命令行界面 argparse

使用 Python 的 argparse 构建命令行界面

在本节中,我们将学习使用 Python 模块构建命令行界面的逐步过程 argparse

使用 argparse 添加脚本描述

第一步是创建一个 ArgumentParser 对象来保存在使用该方法设置解析器之前将命令行解析为 Python 所需的所有信息 parse_args()

注意: 这里我们需要用 parse_args() 方法 vars() 方法以避免错误。您可以参考 Python 文档 以获取更多解释。

接下来我们还给该对象添加描述 ArgumentParser ,简单解释一下该程序的作用。

最简单的方法是:

parser = argparse.ArgumentParser(description = "Load and flip an image with OpenCV")

注意: 根据您的需要,您可能希望有格式更好的描述。

在本例中,我将描述字符串设置为名为的变量 arg_desc ,然后将其传递给 ArgumentParser() .

通过分配 argparse.RawDescriptionHelpFormatter 参数, formatter_class 我能够按照自己想要的方式格式化描述。

# Construct the argument parser and parse the arguments
arg_desc = '''\
        Let's load an image from the command line!
        --------------------------------
            This program loads an image
            with OpenCV and Python argparse!
        '''
parser = argparse.ArgumentParser(formatter_class = argparse.RawDescriptionHelpFormatter,
                                    description= arg_desc)

Python argparse 中的位置参数

接下来,我们需要添加一个位置参数。在本例中,我们有两个参数,一个用于加载图像,另一个用于垂直翻转图像:

parser.add_argument("-i", "--image", metavar="IMAGE", help = "Path to your input image")
parser.add_argument("-f", "--flip", metavar="IMAGE_FLIP", help = "Path to your input image")

我也可以这样写这些代码:

parser.add_argument("image", metavar="IMAGE", help = "Path to your input image")
parser.add_argument("flip", metavar="IMAGE_FLIP", help = "Path to your input image")

"image" "flip" 被称为位置参数,引用属性动作。默认情况下,这是 add_argument() .

但是,您也可以使用一系列标志来提供可选参数,就像我在第一个脚本中所做的那样。这些可选参数以 和 - -- 前缀,并提供一定的灵活性。它们可以替换位置参数。

访问 argparse 值

默认情况下, ArgumentParser 使用 dest 值作为每个对象的“名称”,但可以使用 提供备用名称 metavar 。但请注意,它只会更改消息中显示的名称 help (代替值 dest )。

parser.add_argument("-i", "--image", metavar="IMAGE", help = "Path to your input image")
parser.add_argument("-f", "--flip", metavar="IMAGE_FLIP", help = "Path to your input image")

在这种情况下,我将 metavar 第一个值设置为“IMAGE” dest ,将第二个值设置为“IMAGE_FLIP”。

添加帮助

接下来,我们可以设置 help 参数来提供有关如何使用脚本的指导。在本例中,我设置了 "Path to your input image" 。现在,当我运行以下命令行指令时:

python display_img_opencv.py --help

我有以下输出:

usage: display_img_opencv.py [-h] [-i IMAGE] [-f IMAGE_FLIP]                                                                                                                                                                                            Let's load an image from the command line!                                                                              --------------------------------                                                                                            This program loads an image                                                                                             with OpenCV and Python argparse!                                                                                                                                                                                                                                                                                                                            optional arguments:                                                                                                       -h, --help            show this help message and exit                                                                   -i IMAGE, --image IMAGE                                                                                                                       Path to your input image                                                                          -f IMAGE_FLIP, --flip IMAGE_FLIP                                                                                                              Path to your input image

在下一节中,我们将探讨如何切换布尔标志的默认值。

在 argparse 中切换默认值

Python 支持两种类型的参数:有值的参数和无值的参数。例如,我可以用默认值重写位置参数——在本例中,我们的图像文件 001.jpg .

parser.add_argument("-i", "--image", metavar="IMAGE", default="001.jpg", help = "Path to your input image")
parser.add_argument("-f", "--flip", metavar="IMAGE_FLIP", help = "Path to your input image")

现在,如果我以以下方式运行脚本……

python display_img_opencv.py

…它将显示图像文件 001.jpg .

A Guide to the Python argparse Module

也可能存在没有值的参数。在这种情况下,该参数要么存在,要么不存在。

让我们再举一个例子。我们想要显示一张图片并获取有关该图片的信息,例如其尺寸和通道数。但我们只在 --verbose 指定时才需要这些信息。否则,脚本将仅显示该图片而不返回有关它的任何信息。

import argparse
import cv2

# Construct the argument parser and parse the arguments
arg_desc = '''\
        Let's load an image from the command line!
        --------------------------------
            This program loads an image
            with OpenCV and Python argparse!
        '''

parser = argparse.ArgumentParser(formatter_class = argparse.RawDescriptionHelpFormatter,
                                    description= arg_desc)

parser.add_argument("-i", "--image", default="001.jpg", help = "Path to your input image")
parser.add_argument("-v", "--verbose", action="store_const", const=False, default=True, help = "Path to your input image")
args = vars(parser.parse_args())

# Load the image with "cv2.imread"
image = cv2.imread(args["image"])
# Dimensions, including width, height, and number of channels
(h, w, c) = image.shape[:3]

if args["verbose"]:
   
    # Display the image width, height, and number of channels   
    print("width: {} pixels".format(w))
    print("height: {}  pixels".format(h))
    print("channels: {}".format(c))

    # Display the image
    cv2.imshow("Image", image)
   
else:
   
    # Display the image
    cv2.imshow("Image", image)

cv2.waitKey(0)

参数 action="store_const" 当参数存在时, const 参数值就是参数中设置的值

在上面的行中,脚本将默认显示图像及其相关信息:

python load_img.py -i 001.jpg
width: 640 pixels
height: 427  pixels
channels: 3

图片如下:

A Guide to the Python argparse Module

我们也可以决定不指定任何默认值。在这种情况下,参数 default 将为 None 。在此示例中,我们的参数将变为 False

parser.add_argument("-i", "--image", default="001.jpg", help = "Path to your input image")
parser.add_argument("-v", "--verbose", action="store_const", const=False, help = "Path to your input image")

运行脚本只会显示图像,不显示任何信息。

现在,您可以看到,在布尔参数的情况下,const 和 的值 default 通常相反。

为了便于处理,Python 有快捷操作,称为 store_true store_false store_true const=True 类似 default=False , 则 store_false 相反。

例如我可以通过设置来默认获取图片的信息 action=store_false ,下面是修改后的脚本:

parser.add_argument("-i", "--image", default="001.jpg", help = "Path to your input image")
parser.add_argument("-v", "--verbose", action="store_false", help = "Path to your input image")

现在,运行脚本将显示图像以及与其相关的信息。

如果您想提高您的 Python 技能,请不要忘记查看我们的 Python 编程轨迹 。它将帮助您更快地实现目标。

处理不正确的数据

出于某种原因,您可能会输入无效参数作为命令行参数。在这种情况下,错误将终止脚本。但是,仅使用部分正确的参数就可以运行我们的脚本。

一种方法是添加一个带有 nargs="*" 参数的参数来接受任意数量的参数,然后添加一个不带破折号的接受值的字典 parse_args()

parser.add_argument("-i", "--image", default="001.jpg", help = "Path to your input image")
parser.add_argument("-v", "--verbose", action='store_false', help = "Path to your input image")
parser.add_argument("remainder", nargs="*")
args = vars(parser.parse_args(["v", "i", "image", "verbose"]))

这样,即使我们 dest 在终端中输入了错误的值,我们的脚本仍然会运行。以下是一个例子:

python load_img.py world --cruel happy YEAH
A Guide to the Python argparse Module

如前所述,该脚本忽略了未知值并且仍然有效。

注意: 将项目推送到 GitHub 后,请不要忘记在文件中添加命令行说明 README.md

python display_img_opencv.py image 001.jpg

如果你不熟悉 GitHub,你可以在我们的文章《 如何开始使用 GitHub》 .

将 argparse 与 Pathlib 和 JSON 结合使用

现在,我们来谈谈类型参数。它设置为 str by default ,但您可以根据需要更改此值。

在下面的例子中,我们设置 type=int 因为我们想要计算整数的立方值:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("cube", help="display a cube of a given number",
                    type=int)
args = parser.parse_args()
print(args.cube**3)
python math.py 5                                
125

我们还可以使用其他类构造函数作为变量类型。你可以 在这里了解如何创建 Python 类 .

在下一个示例中,我们将结合 Pathlib 从命令行 argparse 更改目录。

import argparse
from pathlib import Path

parser = argparse.ArgumentParser()
parser.add_argument("--path", type=Path, default=Path(__file__).absolute().parent, help="Path to the target directory")

args = parser.parse_args()
print(args.path, type(args.path))

命令行参数以字符串形式出现;类型参数将采用接受字符串并返回值的函数。此处,设置 type=Path 将把字符串转换为 Path 对象。

如果你好奇 Pathlib 在这里 阅读更多内容 .

现在,假设你想将字典设置为可选参数。你可以使用以下命令来实现 json.loads

import json
import argparse

dict = '{"name": "img.jpg", "person": "Max", "flower": "tulip", "animal": "lion"}'

# Parse a dict
parser = argparse.ArgumentParser()
parser.add_argument('-i', '--input', type=json.loads)
args = parser.parse_args(['-i', dict])
print(args.input)

这将返回以下内容:

{'name': 'img.jpg', 'person': 'Max', 'flower': 'tulip', 'animal': 'lion'}

您可以 在此处 了解有关 JSON 的 。如果您对在 Python 中处理 JSON 文件一无所知,我鼓励您加入我们的课程“ 如何在 Python 中读取和写入 JSON 文件” .

您还可以使用 argparse 序列化任何数据类从/到 JSON YAML .

最后但并非最不重要的一点是,使用 Python argparse ,您可以添加对序列化/反序列化您自己的自定义类型的支持。您可以 在此处 在此处 有关在 Python 中进行序列化/反序列化的更多信息 .

请随意查看 Python argparse 文档 以了解更多详细信息。

您还可以使用 Python argparse 模块做什么?

在本 Python 模块指南中 argparse ,我们学习了如何向 Python 脚本添加命令行界面。我强烈建议您试用该代码并将其添加到您的项目中。它将带来很多价值,而且成本不高。

想要了解更多有关 Python 编程的知识?请查看我关于编写更好的 Python 代码的文章, 获取 更多 提示。 上还有许多其他文章 ,涵盖各种主题。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信小程序

微信扫一扫体验

立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部