你们都说好用的 Python 命令行库:click



做者:HelloGitHub-Prodesire
python

HelloGitHub 的《讲解开源项目》系列,项目地址:https://github.com/HelloGitHub-Team/Articlegit

1、前言

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

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

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

2、介绍

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

它旨在让编写命令行工具的过程既快速又有趣,还能防止因为没法实现预期的 CLI API 所产生挫败感。它有以下三个特色:框架

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

3、快速开始

3.1 业务逻辑

首先定义业务逻辑,是否是感受到有些难以置信呢?函数

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

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

那么在 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.echoprint 的做用类似,但功能更增强大,能处理好 Unicode 和 二进制数据的状况。

3.2 定义参数

很显然,咱们须要针对 countname 来定义它们所对应的参数信息。

  • 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):
    ...

在上面的示例中:

  • 使用装饰器的方式,即定义了参数,又将之与处理逻辑绑定,这真是优雅。和 argparsedocopt 比起来,就少了一步绑定过程
  • 使用 click.command 表示 hello 是对命令的处理
  • 使用 click.option 来定义参数选项
    • 对于 --count 来讲,使用 default 来指定默认值。而因为默认值是数字,进而暗示 --count 选项的类型为数字
    • 对于 --name 来讲,使用 prompt 来指定未输入该选项时的提示语
    • 使用 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.

4、小结

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

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


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

相关文章
相关标签/搜索