让你如绅士般基于描述编写 Python 命令行工具的开源项目:docopt

做者:HelloGitHub- Prodesire

文中涉及的示例代码,已同步更新到 HelloGitHub-Team 仓库python

1、前言

在本系列前面四篇文章中,咱们介绍了 argparse 的方方面面。它无疑是强大的,但使用方式上略显麻烦。须要先设置解析器,再定义参数,再解析命令行,最后实现业务逻辑。git

而今天要介绍的 docopt 则是站在一个全新的视角来审视命令行。你可曾想过,一个命令行程序的帮助信息其实已然包含了这个命令行的完整元信息,那么是否能够经过定义帮助信息来定义命令行呢?docopt 就是基于这样的想法去设计的。github

本系列文章默认使用 Python 3 做为解释器进行讲解。
若你仍在使用 Python 2,请注意二者之间语法和库的使用差别哦~
复制代码

2、介绍

docopt 基于长久以来在帮助信息和手册中描述程序接口的约定,其接口描述是形式化的帮助信息。它可以根据命令行程序中定义的接口描述,来自动生成解析器。编程

3、快速开始

3.1 定义接口描述/帮助信息

第一步要作的就是命令行程序的定义接口描述或者是帮助信息,这样 docopt 就能知道命令行的元信息,从而自动解析。bash

接口描述一般定义在一个模块的文档字符串中,咱们仍然以在 Python 命令行之旅:初探 argparse 的例子为例,讲解如何使用 docopt 来定义接口描述。函数

cmd.py 中,咱们定义以下接口描述:spa

"""Num accumulator. Usage: cmd.py [--sum] <num>... cmd.py (-h | --help) Options: -h --help Show help. --sum Sum the nums (default: find the max). """
复制代码

在上面的接口描述中,咱们定义了命令行程序 cmd.py 接受一个或多个数字 num,而 --sum 选项则是可选,-h--help 则输出帮助信息。命令行

若提供 --sum,则累加给定的数字;反之,取给定多个数字中最大的一个。这个业务逻辑咱们将在后文实现。设计

3.2 解析命令行

定义好接口描述后,就可使用 docopt 进行解析,写法很是简单:code

from docopt import docopt

arguments = docopt(__doc__, options_first=True)
print(arguments)
复制代码

因为咱们以前是将接口描述定义在模块的文档字符串中,那么直接使用 __doc__ 便可得到接口描述。而后使用 docopt 函数便可解析命令行为参数字典。为了支持负数,咱们将 options_first 设置为 True

当咱们执行 python3 cmd.py --sum 1 2 3 时,将会获得以下内容:

{'--help': False,
 '--sum': True,
 '<num>': ['1', '2', '3']}
复制代码

能够看到:

  • 没有提供 -h 或者 --help,因此 arguments--helpFalse
  • 提供了 --sum,因此 arguments--sumTrue
  • 提供了 <num>...1 2 3,因此 arguments<num>['1', '2', '3']

3.3 业务逻辑

得到了解析后的命令行参数,咱们就能够根据本身的业务需求作进一步处理了。 在本文示例中,咱们但愿当用户提供 --sum 选项时,是对给定的一组数字求和;反之则是取最大值,那么就能够这么写:

nums = (int(num) for num in arguments['<num>'])

if arguments['--sum']:
    result = sum(nums)
else:
    result = max(nums)

print(result) # 基于上文的 python3 cmd.py --sum 1 2 3 参数,其结果为 6
复制代码

3.4 代码梳理

使用 docopt 的方式很是简单,咱们将上文的代码汇总下,以有一个更清晰的认识:

# cmd.py
# 1. 定义接口描述
"""Num accumulator. Usage: cmd.py [--sum] <num>... cmd.py (-h | --help) Options: -h --help Show help. --sum Sum the nums (default: find the max). """

from docopt import docopt

# 2. 解析命令行
arguments = docopt(__doc__, options_first=True)

# 3. 业务逻辑
nums = (int(num) for num in arguments['<num>'])

if arguments['--sum']:
    result = sum(nums)
else:
    result = max(nums)

print(result)
复制代码

若咱们须要对一组数字求和,只需执行:

$ python3 cmd.py --sum 1 0 -1
0
复制代码

若咱们须要对一组数字求最大值,只需执行:

$ python3 cmd.py 1 0 -1
1
复制代码

咱们还能够经过 -h--help 参数查看使用说明和帮助,也就是咱们定义的接口描述。

4、小节

docopt 的思路很是简单,就是定义接口描述,而后帮你解析命令行为参数字典,接下来就根据这个字典来编写业务逻辑。

重点就是在于如何定义接口描述,在下一篇文章中,咱们来深刻了解下如何定义命令、选项、位置参数等接口描述。

『讲解开源项目系列』——让对开源项目感兴趣的人再也不畏惧、让开源项目的发起者再也不孤单。跟着咱们的文章,你会发现编程的乐趣、使用和发现参与开源项目如此简单。欢迎留言联系咱们、加入咱们,让更多人爱上开源、贡献开源~

相关文章
相关标签/搜索