大家都说好用的Python命令行库click的使用


Posted in Python onNovember 07, 2019

一、前言

在本系列前面几篇文章中,我们分别介绍了 argparse 和 docopt 的主要功能和用法。它们各具特色,都能出色地完成命令行任务。argparse 是面向过程的,需要先设置解析器,再定义参数,再解析命令行,最后实现业务逻辑。而 docopt 先用声明式的语法定义出参数,再过程式地解析命令行和实现业务逻辑。在一些人看来,这些方式都不够优雅。

而今天要介绍的 click[2] 则是用一种你很熟知的方式来玩转命令行。命令行程序本质上是定义参数和处理参数,而处理参数的逻辑一定是与所定义的参数有关联的。那可不可以用函数和装饰器来实现处理参数逻辑与定义参数的关联呢?而 click 正好就是以这种方式来使用的。

本系列文章默认使用 Python 3 作为解释器进行讲解。若你仍在使用 Python 2,请注意两者之间语法和库的使用差异哦~

二、介绍click

是一个以尽可能少的代码、以组合的方式创建优美的命令行程序的 Python 包。它有很高的可配置性,同时也能开箱即用。

它旨在让编写命令行工具的过程既快速又有趣,还能防止由于无法实现预期的 CLI API 所产生挫败感。它有如下三个特点:

  • 任意嵌套命令
  • 自动生成帮助
  • 支持运行时延迟加载子命令

三、快速开始

3.1 业务逻辑

首先定义业务逻辑,是不是感觉到有些难以置信呢?

不论是 argparse 还是 docopt,业务逻辑都是被放在最后一步,但 click 却是放在第一步。细想想 click 的这种方式才更符合人的思维吧?不论用什么命令行框架,我们最终关心的就是实现业务逻辑,其它的能省则省。

我们以官方示例为例,来介绍 click 的用法和哲学。假设命令行程序的输入是 name 和 count,功能是打印指定次数的名字。

那么在 hello.py 中,很容易写出如下代码:

def hello(count, name): 
  """Simple program that greets NAME for a total of COUNT times.""" 
  for x in range(count): 
    click.echo('Hello %s!' % name)

这段代码的逻辑很简单,就是循环 count 次,使用 click.echo 打印 name。其中,click.echo 和 print 的作用相似,但功能更加强大,能处理好 Unicode 和 二进制数据的情况。

3.2 定义参数

很显然,我们需要针对 count 和 name 来定义它们所对应的参数信息。

  • count 对应为命令行选项 --count,类型为数字,我们希望在不提供参数时,其默认值是 1
  • name 对应为命令行选项 --name,类型为字符串,我们希望在不提供参数时,能给人提示

使用 click,就可以写成下面这样:

from click import click 
 
@click.command() 
@click.option('--count', default=1, help='Number of greetings.') 
@click.option('--name', prompt='Your name', 
       help='The person to greet.') 
def hello(count, name): 
  ...

在上面的示例中:

  1. 使用装饰器的方式,即定义了参数,又将之与处理逻辑绑定,这真是优雅。和 argparse、docopt 比起来,就少了一步绑定过程
  2. 使用 click.command 表示 hello 是对命令的处理
  3. 使用 click.option 来定义参数选项
    1. 对于 --count 来说,使用 default 来指定默认值。而由于默认值是数字,进而暗示 --count 选项的类型为数字
    2. 对于 --name 来说,使用 prompt 来指定未输入该选项时的提示语
    3. 使用 help 来指定帮助信息

不论是装饰器的方式、还是各种默认行为,click 都是像它的介绍所说的那样,让人尽可能少地编写代码,让整个过程变得快速而有趣。

3.3 代码梳理

使用 click 的方式非常简单,我们将上文的代码汇总下,以有一个更清晰的认识:

# hello.py 
import click 
 
@click.command() 
@click.option('--count', default=1, help='Number of greetings.') 
@click.option('--name', prompt='Your name', 
       help='The person to greet.') 
def hello(count, name): 
  """Simple program that greets NAME for a total of COUNT times.""" 
  for x in range(count): 
    click.echo('Hello %s!' % name) 
 
if __name__ == '__main__': 
  hello()

若我们指定次数和名字:

$ python3 hello.py --count 2 --name Eric 
Hello Eric! 
Hello Eric!

若我们什么都不指定,则会提示输入名字,并默认输出一次:

$ python3 hello.py 
Your name: Eric 
Hello Eric!

我们还可以通过 --help 参数查看自动生成的帮助信息:

Usage: hello.py [OPTIONS] 
 
 Simple program that greets NAME for a total of COUNT times. 
 
Options: 
 --count INTEGER Number of greetings. 
 --name TEXT   The person to greet. 
 --help      Show this message and exit.

四、小结

click 的思路非常简单,定义处理函数,通过它的装饰器来定义参数。使用装饰器的绝妙之处就在于把定义和绑定这两个步骤合为一个步骤,使得整个过程变得如丝般顺滑。

click 除了以 Pythonic 的方式让命令行程序的实现变得更加优雅和好用外,还提供了比 argparse 和 docopt 都要强大的功能。在接下来几节中,我们将会逐步揭开它的面纱。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
解决Python字典写入文件出行首行有空格的问题
Sep 27 Python
示例详解Python3 or Python2 两者之间的差异
Aug 23 Python
python linecache 处理固定格式文本数据的方法
Jan 08 Python
PyCharm中代码字体大小调整方法
Jul 29 Python
如何解决django-celery启动后迅速关闭
Oct 16 Python
Python帮你识破双11的套路
Nov 11 Python
服务器端jupyter notebook映射到本地浏览器的操作
Apr 14 Python
Django bulk_create()、update()与数据库事务的效率对比分析
May 15 Python
Python正则表达式如何匹配中文
May 27 Python
python中str内置函数用法总结
Dec 27 Python
pytorch 一行代码查看网络参数总量的实现
May 12 Python
PO模式在selenium自动化测试框架的优势
Mar 20 Python
flask 实现token机制的示例代码
Nov 07 #Python
python3反转字符串的3种方法(小结)
Nov 07 #Python
Python中__repr__和__str__区别详解
Nov 07 #Python
Python通过Manager方式实现多个无关联进程共享数据的实现
Nov 07 #Python
Python上下文管理器类和上下文管理器装饰器contextmanager用法实例分析
Nov 07 #Python
Python中xml和dict格式转换的示例代码
Nov 07 #Python
python对象转字典的两种实现方式示例
Nov 07 #Python
You might like
ThinkPHP之getField详解
2014/06/20 PHP
Yii2框架dropDownList下拉菜单用法实例分析
2016/07/18 PHP
PHP实现的网站目录扫描索引工具
2016/09/08 PHP
javascript级联下拉列表实例代码(自写)
2013/05/10 Javascript
兼容FF和IE的动态table示例自写
2013/10/21 Javascript
js实现固定显示区域内自动缩放图片的方法
2015/07/18 Javascript
jquery简单实现幻灯片的方法
2015/08/03 Javascript
jQuery插件之Tocify动态节点目录菜单生成器附源码下载
2016/01/08 Javascript
在AngularJS中如何使用谷歌地图把当前位置显示出来
2016/01/25 Javascript
Jquery获取第一个子元素简单实例
2016/06/02 Javascript
在react中使用vuex的示例代码
2018/07/30 Javascript
详解html-webpack-plugin插件(用法总结)
2018/09/12 Javascript
微信小程序实现购物页面左右联动
2019/02/15 Javascript
LayUI数据接口返回实体封装的例子
2019/09/12 Javascript
layui多图上传实现删除功能的例子
2019/09/23 Javascript
基于js实现判断浏览器类型代码实例
2020/07/17 Javascript
在vue中封装方法以及多处引用该方法详解
2020/08/14 Javascript
Python 网络编程起步(Socket发送消息)
2008/09/06 Python
python3实现ftp服务功能(服务端 For Linux)
2017/03/24 Python
Python selenium实现微博自动登录的示例代码
2018/05/16 Python
Django在admin后台集成TinyMCE富文本编辑器的例子
2019/08/09 Python
pytorch masked_fill报错的解决
2020/02/18 Python
python的help函数如何使用
2020/06/11 Python
Python try except else使用详解
2021/01/12 Python
使用HTML5拍照示例代码
2013/08/06 HTML / CSS
Html5 Canvas动画基础碰撞检测的实现
2018/12/06 HTML / CSS
美国时尚在线:Showpo
2017/09/08 全球购物
极简鞋类,赤脚的感觉:Lems Shoes
2019/08/06 全球购物
如何手工释放资源
2013/12/15 面试题
函授本科个人自我鉴定
2014/03/25 职场文书
影视后期实训报告
2014/11/05 职场文书
2014年计生协会工作总结
2014/11/21 职场文书
大学生志愿者心得体会
2016/01/15 职场文书
创业计划书之酒吧
2019/12/02 职场文书
python opencv旋转图片的使用方法
2021/06/04 Python
Python实现智慧校园自动评教全新版
2021/06/18 Python