深入浅析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实现破解猜数游戏算法示例
Sep 25 Python
R vs. Python 数据分析中谁与争锋?
Oct 18 Python
Python Grid使用和布局详解
Jun 30 Python
使用python将图片格式转换为ico格式的示例
Oct 22 Python
python Gunicorn服务器使用方法详解
Jul 22 Python
Python Django 实现简单注册功能过程详解
Jul 29 Python
python输出带颜色字体实例方法
Sep 01 Python
基于python的BP神经网络及异或实现过程解析
Sep 30 Python
kafka监控获取指定topic的消息总量示例
Dec 23 Python
如何基于python测量代码运行时间
Dec 25 Python
Python Opencv 通过轨迹(跟踪)栏实现更改整张图像的背景颜色
Mar 09 Python
利用Python pandas对Excel进行合并的方法示例
Nov 04 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
Yii框架实现多数据库配置和操作的方法
2017/05/25 PHP
juqery 学习之三 选择器 子元素与表单
2010/11/25 Javascript
jQuery实现表头固定效果的实例代码
2013/05/24 Javascript
xmlhttp缓存清除的2种解决方法
2013/12/13 Javascript
小米公司JavaScript面试题
2014/12/29 Javascript
利用JQuery写一个简单的异步分页插件
2016/03/07 Javascript
jQuery实现的表格展开伸缩效果实例
2016/09/07 Javascript
彻底学会Angular.js中的transclusion
2017/03/12 Javascript
JavaScript 值类型和引用类型的初次研究(推荐)
2017/07/19 Javascript
在vue中实现简单页面逆传值的方法
2017/11/27 Javascript
利用CDN加速react webpack打包后的文件详解
2018/02/22 Javascript
mocha的时序规则讲解
2019/02/16 Javascript
微信小程序如何实现精确的日期时间选择器
2020/01/21 Javascript
OpenLayer学习之自定义测量控件
2020/09/28 Javascript
Python实现的一个自动售饮料程序代码分享
2014/08/25 Python
Python基础之函数用法实例详解
2014/09/10 Python
python实现用户登陆邮件通知的方法
2015/07/09 Python
Python基于PycURL自动处理cookie的方法
2015/07/25 Python
深入理解Python中的内置常量
2017/05/20 Python
python pandas实现excel转为html格式的方法
2018/10/23 Python
Python实现多属性排序的方法
2018/12/05 Python
Python3调用百度AI识别图片中的文字功能示例【测试可用】
2019/03/13 Python
python词云库wordcloud的使用方法与实例详解
2020/02/17 Python
Win10用vscode打开anaconda环境中的python出错问题的解决
2020/05/25 Python
Python中flatten( ),matrix.A用法说明
2020/07/05 Python
python 密码学示例——理解哈希(Hash)算法
2020/09/21 Python
日本非常有名的内衣丝袜品牌:GUNZE
2017/01/06 全球购物
解释下列WebService名词:WSDL、SOAP、UDDI
2012/06/22 面试题
平面设计专业大学生职业规划书
2014/03/12 职场文书
环保建议书100字
2014/05/14 职场文书
以幸福为主题的活动方案
2014/08/22 职场文书
干部四风问题整改措施思想汇报
2014/10/13 职场文书
初婚初育证明范本
2015/06/18 职场文书
如何做好工作总结!
2019/04/10 职场文书
浅析NIO系列之TCP
2021/06/15 Java/Android
比较几种Redis集群方案
2021/06/21 Redis