在之前的一篇文章中,我们使用了 argparse 来获取命令行参数。这个模块虽然可以出色地完成命令行任务,但由于 argparse 是面向过程的,需要先设置解析器,再定义参数,再解析命令行,最后实现业务逻辑。看着就已经很复杂,对新手很不友好。
今天要介绍的 click 则是用一种简单易读的方式来实现命令行。
一、click介绍
click 是一个以尽可能少的代码、以组合的方式创建优美的命令行程序的 Python 包。
它有如下三个特点:
-
任意嵌套命令
-
自动生成帮助
-
支持运行时延迟加载子命令
二、快速开始
2.1 业务逻辑
首先定义业务逻辑,在 argparse 中,业务逻辑是被放在最后一步,但 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):
print('Hello %s!' % name)
这段代码的逻辑很简单,就是循环 count 次,打印 name。
2.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):
...
在上面的示例中:
使用@click.command() 装饰一个函数,使之成为命令行接口
使用@click.option() 等装饰函数,为其添加命令行选项
对于 --count 来说,使用 default 来指定默认值。而由于默认值是数字,进而暗示 --count 选项的类型为数字
对于 --name 来说,使用 prompt 来指定未输入该选项时的提示语
不论是装饰器的方式、还是各种默认行为,click 都是像它的介绍所说的那样,让人尽可能少地编写代码,让整个过程变得快速而有趣。
2.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模块中的Choice函数,Choice的参数是一个列表,该列表中列出所有可能的值。
import click
@click.command()
@click.option('-c',required=True,type=click.Choice(['start','stop'])) # 限定-c的值为start,或者stop,required表示是否为必填参数
def getcommand(c):
click.echo('command is %s' % c )
if __name__ == '__main__':
getcommand()
场景二:应用程序从命令行读取密码。
使用标准库中的argparse模块只能像输入普通参数一样输入密码。这种方式存在一定安全隐患,例如输入的密码会保存在history中,查看命令历史列表就能获取密码
import click
@click.command()
@click.option('-p',prompt='Your Password',hide_input=True,confirmation_prompt=True)
def getpassword(p):
click.echo('Your Password is : %s' % p)
if __name__ == '__main__':
getpassword()
在Click中,这个问题就能完美的解决,只需要是这prompt为True,那么我们就能交互式输入密码,设置hide_input为True,就能隐藏密码,设置confirmation_prompt为True,就可以进行密码的两次验证,使用起来非常便捷。
四、感慨
从上面的例子来看,click 用法优雅,令人迷醉,简直是 Pythonic 。作者思路清奇,直接将 click 通过装饰器定义参数。让我明白了什么叫纵享丝滑。
参考资料:
[1]
HelloGitHub-Team 仓库: https://github.com/HelloGitHub-Team/Article
[2]
https://www.cnblogs.com/dachenzi/p/7995539.html
扫码关注,获取精选资源