命令行参数处理:Python 的 argparse 模块

和你们中的许多人一样,我经常编写一些一次性脚本来完成任务。这些脚本通常只有短短的20行代码,没有文档,主要用于执行一些清理或维护任务,而且几乎写完就立刻被删除了。

但如果某件事要长久持续下去,我会尝试采取更专业的做法:编写文档和注释、记录日志、检查子命令错误、优雅地处理失败以及处理命令行参数。

事实上,我发现脚本是否处理命令行参数往往决定了它是永久代码还是一次性代码。设计成只做一件事的脚本不需要配置选项,而能够以多种方式运行的代码通常意味着我们拥有一个持久耐用的工具。

本文将向您展示如何使用 Python 中非常强大的argparse模块。如果您之前使用过 shell 或 Perl,您会发现它与典型的 getopts 函数略有不同。它更像是 Go 或其他“大型”语言的解析方式。

在这种情况下,我们将使用以下选项编写一些代码:

  • -f 参数将指定要处理的文件。
  • -v 将启用详细(调试)输出

你会发现,Python 会自动包含帮助输出(-h)。

我们来看一些简单的代码。Python 2 现在已经过时了,我们将使用 Python 3。以下是如何实现上述要求的方法。

我已将以下内容存储在 gronkulator.py 中(这是一个合适的无意义单词,从技术文档到电视节目,各种场合都会用到):

 #!/usr/bin/python3

导入 argparse
导入操作系统
导入系统

def debug(message):
    如果 args.wants_debug:
        打印(消息)

parser = argparse.ArgumentParser(description='互易超量子 gronkulator')
parser.add_argument('-f', help="要处理的文件", dest="文件名", 
    action='store',required=True)
parser.add_argument('-v', help="启用调试", dest="想要调试", 
    action='store_true',required=False,default=False)
args = parser.parse_args()

debug(“已开启调试输出”)
如果 os.path.exists(args.file_name) == False:
    打印(“错误!  文件“%s”不存在 - 中止” % ( args.file_name ))
    sys.exit(1)

print("正在处理文件'%s'" % (args.file_name))

为了方便理解,我把一些代码换行了。我们来快速浏览一遍。

 parser = argparse.ArgumentParser(description='互易超量子 gronkulator')

这样就创建了我们的解析器对象。顺便说一下,你可以根据需要多次解析命令行参数,所以如果你想在本地再次解析,不必担心将 argparse 函数放在某个子程序的深处。

 parser.add_argument('-f', help="要处理的文件", dest="文件名",
    action='store',required=True)
parser.add_argument('-v', help="启用调试", dest="想要调试",
    action='store_true',required=False,default=False)

这里我们添加参数。只需阅读代码,您应该就能明白。`-f` 指定我们要处理的文件名。此参数为必填项(`=True`),其作用是将文件名“存储”到变量 `args.file_name` 中(见下文)。

下一行添加了 `-v` 参数。该参数是可选的,如果设置,则将变量“args.wants_debug”设置为 True,否则设置为 False。这非常方便。执行此行后,即可确保 `args.wants_debug` 变量存在且具有正确的值,并且可以在任何地方引用它。

 args = parser.parse_args()

这段代码会进行实际的参数解析。创建的“args”变量将具有与“目标”变量相对应的值(例如args.file_name、args.wants_debug等)。

之后,我们执行 debug() 函数,然后检查 file_name 是否存在。如果不存在,则报错;否则,我们对该文件进行必要的处理。

我们来试试这段代码:

 # ./gronkulator.py
用法:gronkulator.py [-h] -f FILE_NAME [-v]
gronkulator.py:错误:需要以下参数:-f

请注意,我们没有编写任何“用法”代码——它们全部由 Python 生成。让我们试试 -h 参数:

 # ./gronkulator.py -h
用法:gronkulator.py [-h] -f FILE_NAME [-v]

往复式跨量子格朗克洛尔

可选参数:
-h,--help    显示此帮助信息并退出
-f FILE_NAME  待处理的文件
-v            启用调试

不错。Python 提供了一个完整的帮助图表。

 # ./gronkulator.py -f /tmp/junk 
正在处理文件“/tmp/junk”
# ./gronkulator.py -v -f /tmp/junk 
调试输出已开启
正在处理文件“/tmp/junk”

看起来运行正常。启用 -v 参数可以获取调试输出,禁用则不会,而且脚本能够正确识别 -f 参数。

还有很多其他功能——从添加缩写和长标志到添加帮助信息、解析非sys.argv流、处理已设置的变量等等,不一而足。事实上,主要问题在于argparse本身提供了太多选项,以至于一些读者感到不知所措。但我认为基本操作——例如需要一些标志,稍后访问它们的值——非常简单,可以轻松地从上面的示例复制粘贴。祝您使用愉快!