想要编写更专业、更简洁的代码吗?使用 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
结果如下:
或者我们可以使用以下命令行指令垂直翻转图像:
python display_img_opencv.py --flip 001.jpg
因此,我们的初始图像已绕 x 轴 .
您可以按任意键停止脚本。请随意用您自己的图像尝试一下。
现在,让我们解释如何使用 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
.
也可能存在没有值的参数。在这种情况下,该参数要么存在,要么不存在。
让我们再举一个例子。我们想要显示一张图片并获取有关该图片的信息,例如其尺寸和通道数。但我们只在
--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
图片如下:
我们也可以决定不指定任何默认值。在这种情况下,参数
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
如前所述,该脚本忽略了未知值并且仍然有效。
注意:
将项目推送到 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 代码的文章, 获取 更多 提示。 上还有许多其他文章 ,涵盖各种主题。
发表评论 取消回复