快速上手 Python 命令列模組 Click
阿新 • • 發佈:2020-03-11
![](https://img2020.cnblogs.com/blog/736399/202003/736399-20200311124136314-1380163307.jpg)
# 快速上手 Python 命令列模組 Click
### 關於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"。
好了,這就是今天要說的內容,基本上夠日常操作了。
更多內容,感興趣的朋友可以參考官方