深入浅析Python 命令行模块 Click


Posted in Python onMarch 11, 2020

Click 是用 Python 写的一个第三方模块,用于快速创建命令行。我们知道,Python 内置了一个 Argparse 的标准库用于创建命令行,但使用起来有些繁琐,Click 相比于 Argparse,就好比 requests 相比于 urllib。

关于Click?

说下 Click 模块是干啥的,简单说,它就是把我们的 Python 脚本的一些函数,通过添加带有 Click 关键字的装饰器进行装饰进而将函数调用的形式转化为命令行传参的形式然后执行。听不懂也没关系,我们会一步一步来,基本上按照我的实际应用情况来写的。
 本文不会涉及太多复杂的语法和理论,将会用通俗的语言和大家进行分享。

安装

python3 -m pip install click

一个简单的例子

首先我们创建一个demo.py

import click #(1)
@click.command() #(2)
def main():
 click.echo("hello click") #(3)

if __name__ == '__main__':
 main()

装饰器@click.command()会将我们的函数包装成 click 对象,然后我们可以在函数中调用 click 的一些方法,常用的是click.echo,它的作用类似我们的 print,输出用的。
 通过命令行我们可以这样运行这行代码

python3 demo.py

好了,我们的第一个例子完事了,我们发现此时的代码使用不使用 click好像没什么区别。
 接下来我们就要对它进行拓展了,如果我们需要传入一个数字,然后打印这个时候,我们的代码就可以这样写了。

传入我们的第一个参数

import click

@click.command()
@click.option("-n", "--num", help="input a num")
def main(num):
 click.echo(f"{num =}")

if __name__ == '__main__':
 main()

这里我们前面代码的基础上给函数 main 增加了 @click.option 装饰器。

接下来说下这几个参数的含义

-n:表示我们在命令行指定参数名的时候使用它即可,注意是一个短'-'
--num:是第一个参数的完整名称,我们在程序中接收值的时候使用它。注意是二个短'-'。
help:在命令行输入 "python3 demo.py --help" 的时候,它可以提示我们这个程序有哪些命令可以用。和我们使用命令行一个道理的。

然后我们的函数main的参数名就是,我们要接收的参数的完整名称,同时通过click.echo打印出来。,f"{num=}" 是 Python 3.8 以后的语法糖,如果 num=3 那么它等价于 num = 3。
 最后记得在 __main__ 里执行我们的 main 方法。
 好了,介绍完了代码,我们可以运行了,运行示例:
首先假设我们不知道它有几个参数。

python3 demo.py --help

通过help我们可以得到如下信息

Usage: demo.py [OPTIONS]

Options:
  -n, --num TEXT  input a num  #这是定义该字段help的提示内容
  --help          Show this message and exit.

Usage: 对应我们当前文件名
Options: 是一行一个参数,一个参数分为-开头的缩略参数,和--开头的完整参数名。
 然后我们后面可以看到它的类型是 TEXT。紧接着就是该参数的提示信息,通过 help 我们可以设置。

python3 demo.py -n 3
 #输出
 num ='3'
或者
 python3 demo.py --num 3
 #输出
 num ='3'

上面两者输入方法是等价的使用哪个都行。

现在思考一个问题,如果我们需要 num 的值为数字类型的 3 怎么弄呢?

声明参数类型

这里提供两种方法(当然不仅两种)

 方法一:使用 type 关键字,type 就是 python 里的类型

@click.option("-n", "--num",type=int,help="input a num")

再次执行代码

python3 demo.py -n 4
 #输出
 num =4

同时查看 help 信息的时候 TEXT 变为了 INTEGER。

 方法二:使用 default 关键字,指定默认值为 1

@click.option("-n", "--num",default=1,help="input a num")

将 default 的值设置为数字,我们的命令行就知道了我们的参数类型为 int,
 这里处理指定了参数类型,还设定了默认值。设定为默认值的参数,可以不指定其值,这时候会使用默认值。
 如果我们使用 help 查看信息会发现和上面的方法一没什么区别的。这时候我们可以通过指定另外一个关键字,让它在 help 信息里显示默认值

@click.option("-n", "--num",default=1,help="input a num",show_default=True)

通过加入 show_default 我们可以让 default 的值在 help 信息中显示了,内容格式如下:

Usage: demo.py [OPTIONS]

Options:
  -n, --num INTEGER  input a num  [default: 1]
  --help             Show this message and exit.

再加一个参数

在上面代码的基础上对代码进行部分修改,主要是新添加一个参数 id。

import click

@click.command()
@click.option("-i", "--id", required=True, help="input an id")
@click.option("-n", "--num", type=int, help="input a number", show_default=True)
def main(id, num):
 click.echo(f"your {id=} {num=}")

if __name__ == '__main__':
 main()

给之前的函数再添加 @click.option装饰器即可。
 这里我添加了的参数为 id ,因为一般情况下 id 是不能为空的,所以我们就可以通过required = True对它进行限制,表示该参数为必传参数。如果不传就出现错误

python3 demo.py -n 1234
#没给id传参,出现错误,提示缺少参数。
Usage: demo.py [OPTIONS]
Try "demo.py --help" for help.

Error: Missing option "-i" / "--id".

正确的使用方法应该是

python3 demo.py -i 1 -n 1234

到目前为止一个简答的命令行工具就生成了。接下来说下我用它做过什么事情。

处理实际问题

现在我们有个需求,根据用户名去 mongo 数据库中查找对应的用户登录信息,最终的生成信息格式如下:
不好意思人太多了,让您久等了,您的信息来了!
**************************************************
用户名:lisa
密码: 1234qwer
登录网站: http://www.xxxx.com
**************************************************️
目前密码唯一的不要修改哦!
该条消息不用回复了,谢谢。

一开始我是通过在 python 脚本中加个配置文件,然后通过配置文件的形式进行用户名的修改,但是这种方式不灵活,每次都需要重新运行 Python 代码。或者我们还可以使用 fastapi搭建一个RESTful api的服务,但是我的懒得搭这个服务。最终我选择使用命令行的形式去运行。使用的模块就是今天说的这个 click 模块。
 接下来写一段需要代码:

@click.command()
@click.option('-u', '--user_name', type=str, help='search user_name')
def main(user_name):
 click.echo(f'search user:{user_name}')
 result = m.get_user_info(user_name) #数据库查询
 try:
  info = f"不好意思人太多了,让您久等了,您的信息来了!\n{'*' * 50}\n用户名: {result.get('user_name')}\n" \
   f"密码: {result.get('user_pwd')}\n登录网站: {result.get('url')}\n{'*' * 50}️\n目前密码唯一的不要修改哦!\n该条消息不用回复了,谢谢。"
 except Exception as e:
  info = "Not Found"
 click.echo(info)
if __name__ == '__main__':
 main()

通过上面的码我们就可以通过命令行的形式进行查询了。

python3 demo.py -u 1234

非常的方便。
 如果这个时候,我需要一个临时添加用户的功能,就需要重新写一个函数了,
 然后我们在命令行中如何控制两个函数的运行呢?这就是接下来要说的组。

创建组的形式

所谓的创建组,就是通过一个主入口函数,去关联其他的函数,然后其他的函数名可以作为命令直接使用。
 好了首先创建一个主入口函数

@click.group()
def main():
 pass

这个时候我们发现 main 上面的装饰器变为了@click.group()。
 我们通过它准备创建一个命令行组。接下来我们开始创建组成员,所谓的组成员就是一个函数。

@main.command()
@click.option('-u', '--user_name', type=str, help='add user_name')
def get_user(user_name):
  click.echo(f'search user:{user_name}')

这个组成员的作用和它的函数名是一样的就是查询用户信息。
 这里需要注意的是组成员的装饰器由原来的
@click.command变为了@main.command
main 就是上面 main 方法名。然后同样下面的 option 是声明一些参数。
 接下来我们创建第二个组成员,用来添加用户信息。

@main.command()
@click.option('-u', '--user_name', required=True, type=str, help="要添加的用户名")
@click.option('-p', '--password', required=True, type=str, help="要添加的密码")
@click.option('-t', '--id_type', required=True, default="phone", type=str, help="添加的账户类型",show_default=True)
def add_user(user_name, password, id_type):
  #do something.....
  click.echo(f"{user_name=} {password=} {id_type=}")

首先通过@main.command()将它加入到组。然后就是 option 一系列添加参数的操作。这个具体的参数信息上面都说了这里就不提了。好了我们就创建这两个成员,
 如果需要其他的功能,比如说删除用户,可以继续添加一个 delete_user 函数,以此类推。

下面我就说下如何执行上面的两个成员函数。

首先,先看下它的 help 命令,都有什么内容,一般不知道一个命令行应用有什么命令参数的我时候我们可以使用它。

python3 demo.py --help

输出以下内容

Usage: demo.py [OPTIONS] COMMAND [ARGS]...

Options:
  --help  Show this message and exit.

Commands:
  add-user
  get-user

其中 Commands 就是我们的成员函数的调用命令,需要注意一下它将函数原来的"_"变为了“-”。
 然后我们就可以调用查询方法了

python3 demo.py get-user -u 123

然后我们就可以得到结果

search user:123

同样的调用添加用户信息的方法。

python3 demo.py add-user -u 123 -p "1234qwer"

因为-t不是必传参数所以我们可以忽略,使用默认值"phone"。
 好了,这就是今天要说的内容,基本上够日常操作了。

更多内容,感兴趣的朋友可以参考官方文档。

到此这篇关于深入浅析Python 命令行模块 Click的文章就介绍到这了,更多相关Python 命令行模块 Click内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python操作MySQL数据库的方法分享
May 29 Python
在Docker上开始部署Python应用的教程
Apr 17 Python
Python定时执行之Timer用法示例
May 27 Python
使用Python爬取最好大学网大学排名
Feb 24 Python
Python面向对象程序设计OOP深入分析【构造函数,组合类,工具类等】
Jan 05 Python
对python For 循环的三种遍历方式解析
Feb 01 Python
Python常用爬虫代码总结方便查询
Feb 25 Python
PyTorch中的padding(边缘填充)操作方式
Jan 03 Python
python 日志 logging模块详细解析
Mar 31 Python
python计算Content-MD5并获取文件的Content-MD5值方式
Apr 03 Python
Django admin管理工具TabularInline类用法详解
May 14 Python
Python中全局变量和局部变量的理解与区别
Feb 07 Python
python字典和json.dumps()的遇到的坑分析
Mar 11 #Python
解决pyecharts运行后产生的html文件用浏览器打开空白
Mar 11 #Python
在django admin详情表单显示中添加自定义控件的实现
Mar 11 #Python
django admin 添加自定义链接方式
Mar 11 #Python
django xadmin 管理器常用显示设置方式
Mar 11 #Python
django从后台返回html代码的实例
Mar 11 #Python
Django-xadmin后台导入json数据及后台显示信息图标和主题更改方式
Mar 11 #Python
You might like
php输入流php://input使用示例(php发送图片流到服务器)
2013/12/25 PHP
php设置session值和cookies的学习示例
2014/03/21 PHP
php中使用gd库实现下载网页中所有图片
2015/05/12 PHP
详解php中反射的应用
2016/03/15 PHP
jquery 关键字“拖曳搜索”之“拖曳”以及 图片“提示自适应放大”效果 的实现
2010/04/18 Javascript
基于Jquery与WebMethod投票功能实现代码
2011/01/19 Javascript
jquery 读取页面load get post ajax 四种方式代码写法
2011/04/02 Javascript
找出字符串中出现次数最多的字母和出现次数精简版
2012/11/07 Javascript
Js 获取Gridview选中行的内容操作步骤
2013/02/05 Javascript
jQuery实现可拖动的浮动层完整代码
2013/05/27 Javascript
JavaScript中实现PHP的打乱数组函数shuffle实例
2014/10/11 Javascript
Javascript快速排序算法详解
2014/12/03 Javascript
使用AOP改善javascript代码
2015/05/01 Javascript
Angular中$compile源码分析
2016/01/28 Javascript
自动完成的搜索框javascript实现
2016/02/26 Javascript
基于javascript实现精确到毫秒的倒计时限时抢购
2016/04/17 Javascript
JavaScript常见的五种数组去重的方式
2016/12/15 Javascript
Bootstrap表单制作代码
2017/03/17 Javascript
JS简单判断字符在另一个字符串中出现次数的2种常用方法
2017/04/20 Javascript
解决vue处理axios post请求传参的问题
2018/03/05 Javascript
浅谈KOA2 Restful方式路由初探
2019/03/14 Javascript
微信小程序动态显示项目倒计时
2019/06/20 Javascript
JavaScript用document.write()输出换行的示例代码
2020/11/26 Javascript
vue常用高阶函数及综合实例
2021/02/25 Vue.js
Python3.5集合及其常见运算实例详解
2019/05/01 Python
Python 寻找局部最高点的实现
2019/12/05 Python
Django集成celery发送异步邮件实例
2019/12/17 Python
python生成13位或16位时间戳以及反向解析时间戳的实例
2020/03/03 Python
python爬虫爬取图片的简单代码
2021/01/18 Python
Html5 new XMLHttpRequest()监听附件上传进度
2021/01/14 HTML / CSS
含精油的天然有机化妆品:Indemne
2019/08/27 全球购物
法国亚马逊官方网站:Amazon.fr
2020/12/19 全球购物
医学检验专业大学生求职信
2013/11/18 职场文书
建筑工程专业大学生求职信
2014/04/23 职场文书
圣诞节开幕词
2015/01/29 职场文书
2016春季田径运动会广播稿
2015/12/21 职场文书