深入浅析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 当前全局变量和入口参数的所有属性
Jul 01 Python
python 实现插入排序算法
Jun 05 Python
在Django中管理Users和Permissions以及Groups的方法
Jul 23 Python
Python入门_浅谈字符串的分片与索引、字符串的方法
May 16 Python
Java编程迭代地删除文件夹及其下的所有文件实例
Feb 10 Python
python爬取网页内容转换为PDF文件
Jul 28 Python
Python实现堡垒机模式下远程命令执行操作示例
May 09 Python
PyQt5显示GIF图片的方法
Jun 17 Python
Python的pygame安装教程详解
Feb 10 Python
Django实现将views.py中的数据传递到前端html页面,并展示
Mar 16 Python
Python Tornado实现WEB服务器Socket服务器共存并实现交互的方法
May 26 Python
python for循环赋值问题
Jun 03 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
为php4加入动态flash文件的生成的支持
2006/10/09 PHP
php实现的ping端口函数实例
2014/11/12 PHP
php中final关键字用法分析
2016/12/07 PHP
js为数字添加逗号并格式化数字的代码
2013/08/23 Javascript
js 剪切板应用clipboardData详细解析
2013/12/17 Javascript
前端必备神器 Snap.svg 弹动效果
2014/11/10 Javascript
BootstrapValidator不触发校验的实现代码
2016/09/28 Javascript
使用Bootstrap Tabs选项卡Ajax加载数据实现
2016/12/23 Javascript
深入理解在JS中通过四种设置事件处理程序的方法
2017/03/02 Javascript
dropload.js插件下拉刷新和上拉加载使用详解
2017/10/20 Javascript
js实现复制功能(多种方法集合)
2018/01/06 Javascript
ajax前台后台跨域请求处理方式
2018/02/08 Javascript
关于layui 实现点击按钮添加一行(方法渲染创建的table)
2019/09/29 Javascript
javascript实现函数柯里化与反柯里化过程解析
2019/10/08 Javascript
jquery选择器和属性对象的操作实例分析
2020/01/10 jQuery
React实现评论的添加和删除
2020/10/20 Javascript
Javascript中的奇葩知识,你知道吗?
2021/01/25 Javascript
[51:36]Optic vs Newbee 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/18 DOTA
Python使用logging结合decorator模式实现优化日志输出的方法
2016/04/16 Python
Python如何为图片添加水印
2016/11/25 Python
Python编程中NotImplementedError的使用方法
2018/04/21 Python
Django调用百度AI接口实现人脸注册登录代码实例
2020/04/23 Python
python网络编程之五子棋游戏
2020/05/14 Python
CSS3圆角边框和边界图片效果实例
2016/07/01 HTML / CSS
关于box-sizing的全面理解
2016/07/28 HTML / CSS
美国受欢迎的眼影品牌:BH Cosmetics
2016/10/25 全球购物
IRO美国官网:法国服装品牌
2018/03/06 全球购物
北美主要的汽车零部件零售商:AutoShack.com
2019/02/23 全球购物
令人啧啧称赞的经理推荐信
2013/11/07 职场文书
会计主管岗位职责
2014/01/03 职场文书
2014年信访维稳工作总结
2014/12/08 职场文书
2014年纳税评估工作总结
2014/12/23 职场文书
工作检讨书怎么写
2015/01/23 职场文书
2015年妇产科工作总结
2015/05/18 职场文书
2019年大学生暑期社会实践调查报告模板
2019/11/07 职场文书
zabbix配置nginx监控的实现
2022/05/25 Servers