让你如绅士般基于描述编写 Python 命令行工具的开源项目:docopt
作者:HelloGitHub-Prodesire
HelloGitHub 的《讲解开源项目》系列,项目地址:https://github.com/HelloGitHub-Team/Article
一、前言
在本系列前面四篇文章中,我们介绍了 argparse
的方方面面。它无疑是强大的,但使用方式上略显麻烦。需要先设置解析器,再定义参数,再解析命令行,最后实现业务逻辑。
而今天要介绍的 docopt 则是站在一个全新的视角来审视命令行。你可曾想过,一个命令行程序的帮助信息其实已然包含了这个命令行的完整元信息,那么是否可以通过定义帮助信息来定义命令行呢?docopt
就是基于这样的想法去设计的。
本系列文章默认使用 Python 3 作为解释器进行讲解。
若你仍在使用 Python 2,请注意两者之间语法和库的使用差异哦~
二、介绍
docopt 基于长久以来在帮助信息和手册中描述程序接口的约定,其接口描述是形式化的帮助信息。它能够根据命令行程序中定义的接口描述,来自动生成解析器。
三、快速开始
3.1 定义接口描述/帮助信息
第一步要做的就是命令行程序的定义接口描述或者是帮助信息,这样 docopt
就能知道命令行的元信息,从而自动解析。
接口描述通常定义在一个模块的文档字符串中,我们仍然以在 Python 命令行之旅:初探 argparse
的例子为例,讲解如何使用 docopt
来定义接口描述。
在 cmd.py
中,我们定义如下接口描述:
"""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
进行解析,写法非常简单:
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
中--help
为False
- 提供了
--sum
,所以arguments
中--sum
为True
- 提供了
<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
参数查看使用说明和帮助,也就是我们定义的接口描述。
四、小节
docopt
的思路非常简单,就是定义接口描述,然后帮你解析命令行为参数字典,接下来就根据这个字典来编写业务逻辑。
重点就是在于如何定义接口描述,在下一篇文章中,我们来深入了解下如何定义命令、选项、位置参数等接口描述。
『讲解开源项目系列』——让对开源项目感兴趣的人不再畏惧、让开源项目的发起者不再孤单。跟着我们的文章,你会发现编程的乐趣、使用和发现参与开源项目如此简单。欢迎留言联系我们、加入我们,让更多人爱上开源、贡献开源~
让你如绅士般基于描述编写 Python 命令行工具的开源项目:docopt的更多相关文章
- 让你如“老”绅士般编写 Python 命令行工具的开源项目:docopt
作者:HelloGitHub-Prodesire HelloGitHub 的<讲解开源项目>系列,项目地址:https://github.com/HelloGitHub-Team/Arti ...
- 个推Node.js 微服务实践:基于容器的一站式命令行工具链
作者:个推Node.js 开发工程师 之诺 背景与摘要 由于工程数量的快速增长,个推在实践基于 Node.js 的微服务开发的过程中,遇到了如下问题: 1. 每次新建项目都需要安装一次依赖,这些依赖之 ...
- xterm.js 基于websocket 链接容器 命令行工具
<template> <div> <el-dialog title="命令" :visible.sync="dialogTableVisib ...
- 10. 通过 Dockerfile 编写 linux 命令行工具
测试 linux 压力的工具 一. 实际操作 1. 创建一个 ubuntu 的容器 docker run -it ubuntu 2. 安装 stress 工具 apt-get update & ...
- 如何创建一个基于命令行工具的跨平台的 NuGet 工具包
命令行可是跨进程通信的一种非常方便的手段呢,只需启动一个进程传入一些参数即可完成一些很复杂的任务.NuGet 为我们提供了一种自动导入 .props 和 .targets 的方法,同时还是一个 .NE ...
- nodejs 编写(添加时间戳)命令行工具 timestamp
Nodejs除了编写服务器端程序还可以编写命令行工具,如gulp.js就是Nodejs编写的. 接下来我们来实现一个添加时间戳的命令: $ timestamp action https://www.n ...
- 如何用Node编写命令行工具
0. 命令行工具 当全局安装模块之后,我们可以在控制台下执行指定的命令来运行操作,如果npm一样.我把这样的模块称之为命令行工具模块(如理解有偏颇,欢迎指正) 1.用Node编写命令行工具 在Node ...
- Node.js 命令行工具的编写
日常开发中,编写 Node.js 命令行工具来完成一些小任务是很常见的操作.其编写也不难,和日常编写 Node.js 代码并无二致. package.json 中的 bin 字段 一个 npm 模块, ...
- 使用.Net Core编写命令行工具(CLI)
命令行工具(CLI) 命令行工具(CLI)是在图形用户界面得到普及之前使用最为广泛的用户界面,它通常不支持鼠标,用户通过键盘输入指令,计算机接收到指令后,予以执行. 通常认为,命令行工具(CLI)没有 ...
随机推荐
- NLP(二) 获取数据源和规范化
Why we do this 将获取的数据统一格式,得到规范化和结构化得数据 字符串操作 # 创建字符串列表和字符串对象 namesList = ['Tuffy','Ali','Nysha','Tim ...
- 面向对象程序设计(Java) 第1周学习指导及要求
面向对象程序设计(Java)第1周学习指导及要求 (2019.8.30-2019.9.2) 学习目标 了解课程上课方式及老师教学要求,掌握课程学习必要的软件工具: 理解JVM.JRE与JDK等概念 ...
- 【Ehcache】基础知识学习
一.Ehcache概述 1.1 简介 1.2 Ehcache的主要特性 二.Ehcache使用介绍 2.1 Ehcache缓存过期策略 2.2 如何解决缓存与db不同步的问题. 三.Ehcache 基 ...
- centos 6.8 下没有yum命令解决方法(报错: -bash: yum: command not found)
1.去 http://mirrors.163.com/centos/6/os/x86_64/Packages/ 地址下载4个rpm安装包:python-iniparse-0.3.1-2.1.el6.n ...
- Linux基础Day001-001章
运维工作职责:(运行和维护服务器) 1.数据不能丢失, 2.保障网站7*24H正常运行,--一直运行; 3.用户体验要好,--打开网站速度要快 服务器核心硬件(硬盘,内存,CPU) 尺寸: 1U-4. ...
- 致初学者(三): HDU 2033~ 2043题解
下面继续给出HDU 2033~2043的AC程序,供大家参考.2033~2043这10道题就被归结为“ACM程序设计期末考试(2006/06/07) ”和“2005实验班短学期考试 ”. HDU 20 ...
- 阿里云 centos7 64位搭建JAVA环境-----安装JDK(2)
mysql安装好以后,把jdk环境配置一下. 首先下载jdk 8,在官网下载. 找到链接 http://download.oracle.com/otn-pub/java/jdk/8u171-b11/5 ...
- Java反序列化漏洞原理解析(案例未完善后续补充)
序列化与反序列化 序列化用途:方便于对象在网络中的传输和存储 java的反序列化 序列化就是将对象转换为流,利于储存和传输的格式 反序列化与序列化相反,将流转换为对象 例如:json序列化.XML序列 ...
- valueForKey与valueForKeyPath 区别
1.删除数组中重复的数据 2.valueForKeyPath:可以深层次取到子属性,不管隐藏的多深 valueForKey:无法取到深层次子属性 但是也有其相似的地方: 比如:快速找到字典数组中ke ...
- charles 重写工具/rewrite Srttings
本文参考:charles 重写工具 rewrite Srttings 重写工具/rewrite Srttings and rewrite rule 功能:在通过charles时修改请求和响应 重写工具 ...