快速上手 Python 命令行模塊 Click
點擊上方“Python學(xué)習(xí)開發(fā)”,選擇“加為星標(biāo)”
第一時間關(guān)注Python技術(shù)干貨!

關(guān)于Click?
說下 Click 模塊是干啥的,簡單說,它就是把我們的 Python 腳本的一些函數(shù),通過
添加帶有 Click 關(guān)鍵字的裝飾器進(jìn)行裝飾進(jìn)而將函數(shù)調(diào)用的形式轉(zhuǎn)化為命令行傳參的形式然后執(zhí)行。聽不懂也沒關(guān)系,我們會一步一步來,基本上按照我的實際應(yīng)用情況來寫的。
本文不會涉及太多復(fù)雜的語法和理論,將會用通俗的語言和大家進(jìn)行分享。
安裝
python3?-m?pip?install?click
一個簡單的例子
首先我們創(chuàng)建一個demo.py
import?click?#(1)
@click.command()?#(2)
def?main():
????click.echo("hello?click")?#(3)
if?__name__?==?'__main__':
????main()
裝飾器@click.command()會將我們的函數(shù)包裝成 click 對象,然后我們可以在函數(shù)中調(diào)用 click 的一些方法,常用的是click.echo,它的作用類似我們的 print,輸出用的。
通過命令行我們可以這樣運行這行代碼
python3?demo.py
好了,我們的第一個例子完事了,我們發(fā)現(xiàn)此時的代碼使用不使用 click好像沒什么區(qū)別。
接下來我們就要對它進(jìn)行拓展了,如果我們需要傳入一個數(shù)字,然后打印這個時候,我們的代碼就可以這樣寫了。
傳入我們的第一個參數(shù)
import?click
@click.command()
@click.option("-n",?"--num",?help="input?a?num")
def?main(num):
????click.echo(f"{num?=}")
if?__name__?==?'__main__':
????main()
這里我們前面代碼的基礎(chǔ)上給函數(shù) main 增加了 @click.option 裝飾器。
接下來說下這幾個參數(shù)的含義
-n:表示我們在命令行指定參數(shù)名的時候使用它即可,注意是一個短'-'
--num:是第一個參數(shù)的完整名稱,我們在程序中接收值的時候使用它。注意是二個短'-'。
help:在命令行輸入 "python3 demo.py --help" 的時候,它可以提示我們這個程序有哪些命令可以用。和我們使用命令行一個道理的。
然后我們的函數(shù)main的參數(shù)名就是,我們要接收的參數(shù)的完整名稱,同時通過click.echo打印出來。,f"{num=}" 是 Python 3.8 以后的語法糖,如果 num=3 那么它等價于 num = 3。
最后記得在 __main__ 里執(zhí)行我們的 main 方法。
好了,介紹完了代碼,我們可以運行了,運行示例:
首先假設(shè)我們不知道它有幾個參數(shù)。
python3?demo.py?--help?
通過help我們可以得到如下信息
Usage:?demo.py?[OPTIONS]
Options:
??-n,?--num?TEXT??input?a?num??#這是定義該字段help的提示內(nèi)容
??--help??????????Show?this?message?and?exit.
Usage: 對應(yīng)我們當(dāng)前文件名
Options: 是一行一個參數(shù),一個參數(shù)分為-開頭的縮略參數(shù),和--開頭的完整參數(shù)名。
然后我們后面可以看到它的類型是 TEXT。緊接著就是該參數(shù)的提示信息,通過 help 我們可以設(shè)置。
?python3?demo.py?-n?3
?#輸出
?num?='3'
或者
?python3?demo.py?--num?3
?#輸出
?num?='3'
上面兩者輸入方法是等價的使用哪個都行。
現(xiàn)在思考一個問題,如果我們需要 num 的值為數(shù)字類型的 3 怎么弄呢?
聲明參數(shù)類型
這里提供兩種方法(當(dāng)然不僅兩種)
方法一:使用 type 關(guān)鍵字,type 就是 python 里的類型
@click.option("-n",?"--num",type=int,help="input?a?num")
再次執(zhí)行代碼
?python3?demo.py?-n?4
?#輸出
?num?=4
同時查看 help 信息的時候 TEXT 變?yōu)榱?INTEGER。
方法二:使用 default 關(guān)鍵字,指定默認(rèn)值為 1
@click.option("-n",?"--num",default=1,help="input?a?num")
將 default 的值設(shè)置為數(shù)字,我們的命令行就知道了我們的參數(shù)類型為 int,
這里處理指定了參數(shù)類型,還設(shè)定了默認(rèn)值。設(shè)定為默認(rèn)值的參數(shù),可以不指定其值,這時候會使用默認(rèn)值。
如果我們使用 help 查看信息會發(fā)現(xiàn)和上面的方法一沒什么區(qū)別的。這時候我們可以通過指定另外一個關(guān)鍵字,讓它在 help 信息里顯示默認(rèn)值
@click.option("-n",?"--num",default=1,help="input?a?num",show_default=True)
通過加入 show_default 我們可以讓 default 的值在 help 信息中顯示了,內(nèi)容格式如下:
Usage:?demo.py?[OPTIONS]
Options:
??-n,?--num?INTEGER??input?a?num??[default:?1]
??--help?????????????Show?this?message?and?exit.
再加一個參數(shù)
在上面代碼的基礎(chǔ)上對代碼進(jìn)行部分修改,主要是新添加一個參數(shù) 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()
給之前的函數(shù)再添加 @click.option裝飾器即可。
這里我添加了的參數(shù)為 id ,因為一般情況下 id 是不能為空的,所以我們就可以通過required = True對它進(jìn)行限制,表示該參數(shù)為必傳參數(shù)。如果不傳就出現(xiàn)錯誤
python3?demo.py?-n?1234?
#沒給id傳參,出現(xiàn)錯誤,提示缺少參數(shù)。
Usage:?demo.py?[OPTIONS]
Try?"demo.py?--help"?for?help.
Error:?Missing?option?"-i"?/?"--id".
正確的使用方法應(yīng)該是
python3?demo.py?-i?1?-n?1234
到目前為止一個簡答的命令行工具就生成了。接下來說下我用它做過什么事情。
處理實際問題
現(xiàn)在我們有個需求,根據(jù)用戶名去 mongo 數(shù)據(jù)庫中查找對應(yīng)的用戶登錄信息,最終的生成信息格式如下:
不好意思人太多了,讓您久等了,您的信息來了!
**************************************************
用戶名:lisa
密碼:?1234qwer
登錄網(wǎng)站:?http://www.xxxx.com
**************************************************?
目前密碼唯一的不要修改哦!
該條消息不用回復(fù)了,謝謝。
一開始我是通過在 python 腳本中加個配置文件,然后通過配置文件的形式進(jìn)行用戶名的修改,但是這種方式不靈活,每次都需要重新運行 Python 代碼。或者我們還可以使用 fastapi搭建一個RESTful api的服務(wù),但是我的懶得搭這個服務(wù)。最終我選擇使用命令行的形式去運行。使用的模塊就是今天說的這個 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)?#數(shù)據(jù)庫查詢
????try:
????????info?=?f"不好意思人太多了,讓您久等了,您的信息來了!\n{'*'?*?50}\n用戶名:?{result.get('user_name')}\n"?\
????????????f"密碼:?{result.get('user_pwd')}\n登錄網(wǎng)站:?{result.get('url')}\n{'*'?*?50}?\n目前密碼唯一的不要修改哦!\n該條消息不用回復(fù)了,謝謝。"
????except?Exception?as?e:
????????info?=?"Not?Found"
????click.echo(info)
if?__name__?==?'__main__':
????main()
通過上面的碼我們就可以通過命令行的形式進(jìn)行查詢了。
python3?demo.py?-u?1234
非常的方便。
如果這個時候,我需要一個臨時添加用戶的功能,就需要重新寫一個函數(shù)了,
然后我們在命令行中如何控制兩個函數(shù)的運行呢?這就是接下來要說的組。
創(chuàng)建組的形式
所謂的創(chuàng)建組,就是通過一個主入口函數(shù),去關(guān)聯(lián)其他的函數(shù),然后其他的函數(shù)名可以作為命令直接使用。
好了首先創(chuàng)建一個主入口函數(shù)
@click.group()
def?main():
???pass
這個時候我們發(fā)現(xiàn) main 上面的裝飾器變?yōu)榱?code style="font-size:inherit;color:rgb(248,35,117);">@click.group()。
我們通過它準(zhǔn)備創(chuàng)建一個命令行組。接下來我們開始創(chuàng)建組成員,所謂的組成員就是一個函數(shù)。
@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}')
這個組成員的作用和它的函數(shù)名是一樣的就是查詢用戶信息。
這里需要注意的是組成員的裝飾器由原來的@click.command變?yōu)榱?code style="font-size:inherit;color:rgb(248,35,117);">@main.command。
main 就是上面 main 方法名。然后同樣下面的 option 是聲明一些參數(shù)。
接下來我們創(chuàng)建第二個組成員,用來添加用戶信息。
@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 一系列添加參數(shù)的操作。這個具體的參數(shù)信息上面都說了這里就不提了。好了我們就創(chuàng)建這兩個成員,
如果需要其他的功能,比如說刪除用戶,可以繼續(xù)添加一個 delete_user 函數(shù),以此類推。
下面我就說下如何執(zhí)行上面的兩個成員函數(shù)。
首先,先看下它的 help 命令,都有什么內(nèi)容,一般不知道一個命令行應(yīng)用有什么命令參數(shù)的我時候我們可以使用它。
python3?demo.py?--help
輸出以下內(nèi)容
Usage:?demo.py?[OPTIONS]?COMMAND?[ARGS]...
Options:
??--help??Show?this?message?and?exit.
Commands:
??add-user
??get-user
其中 Commands 就是我們的成員函數(shù)的調(diào)用命令,需要注意一下它將函數(shù)原來的"_"變?yōu)榱恕?”。
然后我們就可以調(diào)用查詢方法了
python3?demo.py?get-user?-u?123
然后我們就可以得到結(jié)果
search?user:123
同樣的調(diào)用添加用戶信息的方法。
python3?demo.py?add-user?-u?123?-p?"1234qwer"
因為-t不是必傳參數(shù)所以我們可以忽略,使用默認(rèn)值"phone"。
好了,這就是今天要說的內(nèi)容,基本上夠日常操作了。
更多內(nèi)容,感興趣的朋友可以參考官方文檔。
之前出了個 asyncio 的 chat 文章系列課,受到大家的喜歡,學(xué)完了這些基礎(chǔ)就可以學(xué)習(xí)這個異步爬蟲課了。我們使用的模塊是aiohttp,它可以輕松實現(xiàn)一個輕量級的高并發(fā)爬蟲,感興趣的朋友趕緊掃碼預(yù)定吧。另外,告訴大家好消息,訂購后分享自己的二維碼,還有一定的傭金哦。
推薦閱讀
添加微信[gopython3].回復(fù):回復(fù)Go或者Python加對應(yīng)技術(shù)群。
