一. 認識 Click 庫
連載關(guān)于命令行系列文章,我們提到了 Python 標準庫模塊 argparse 可用于解析命令行參數(shù)~ 但由于 argparse 使用復(fù)雜,add_argument 方法參數(shù)眾多。為此,第三方庫模塊 click 應(yīng)運而生,極大地改善了 argparse 的易用性。
注:
Click第三方庫由 Flask 的作者 Armin Ronacher 開發(fā)。Click相較于argparse較好比requests相較于urllib。
使用 click 之前,需要先進行安裝:
pip install click
Click 模塊構(gòu)建 Python 命令行,分以下 2 步走:
- 使用
@click.command()裝飾器,使被裝飾的函數(shù)成為命令行接口; - 使用
@click.option()等裝飾器,添加命令行選項。
下面是一個簡單的示例:
import click
@click.command()
@click.option('--count', default=1, help='Number of grettings.')
@click.option('--name', prompt='Your name', help='The person to greet.')
def hello(count, name):
"""Simple program that greets NAME for a total of COUNT times."""
for x in range(count):
click.echo('Hello %s' % name)
if __name__ == '__main__':
hello()
函數(shù) hello 接受兩個參數(shù) count 和 name ,分別從命令行中讀取值。程序中用到了 click 模塊的 command option 以及 echo ,它們的作用如下:
-
command使得函數(shù)hello作為命令行接口; -
option添加命令行選項; -
click.echo主要是從兼容性考慮:Python2 的print是語句,而 Python3 中則為函數(shù)。
運行結(jié)果:

由于我們剛剛在添加 name 參數(shù)時,指定了 prompt='Your name' ,因此當執(zhí)行命令行時,如果沒有指定 --name ,Click 將提示用戶在交互模式下輸入。--count 參數(shù)在定義時,我們指定了默認值 default=1 。
此外,和 argparse 一樣,click 也會自動為我們生成好幫助信息:

二. 添加參數(shù)的詳細用法
Click 庫提供的裝飾器 @click.option 通過指定命令行選項的名稱,從命令行讀取參數(shù)值,再將其傳遞給函數(shù)。其中,option 常用的設(shè)置參數(shù)如下:
-
default設(shè)置命令行參數(shù)的默認值; -
help參數(shù)說明; -
type指定參數(shù)類型,如stringintfloat; -
prompt當命令行未指定相應(yīng)參數(shù)時,會根據(jù)prompt提示用戶輸入; -
nargs指定命令行參數(shù)接受的值的個數(shù)。
示例 1 標準庫的 argparse 可以通過 nargs 配置參數(shù)的個數(shù),通過 type 設(shè)置參數(shù)的數(shù)據(jù)類型。在 click 中也可以實現(xiàn):
import click
@click.command()
@click.option('--pos', nargs=2, type=float)
def example(pos):
click.echo('pos={}'.format(pos))
if __name__ == '__main__':
example()
運行結(jié)果:

上述的例子中,程序會自動將參數(shù)轉(zhuǎn)換為浮點數(shù),并且以元組的形式賦值給變量 pos 。
示例 2 對于枚舉類型的命令行參數(shù),可以指定 type 為 click.Choice 實例。Choice 的參數(shù)是一個列表,改列表列出所有可能的值。
import click
@click.command()
@click.option('--subject', type=click.Choice(['math','chinese','english']))
def score(subject):
click.echo('{} score: 100'.format(subject))
if __name__ == '__main__':
score()
運行結(jié)果:

示例 3 交互式地輸入密碼
在 argparse 模塊中,輸入密碼只能像普通參數(shù)一樣設(shè)置,這將帶來一定的安全隱患:使用 history 就可以輕易獲取到我們的密碼。
在 click 中,上述問題得到了非常優(yōu)美的解決:只需要設(shè)置 prompt=True ,就能夠交互式地輸入密碼;設(shè)置 hide_input=True 即可隱藏我們的命令行輸入;設(shè)置 confirmation_prompt=True 就可以進行密碼的兩次驗證。
import click
from werkzeug.security import generate_password_hash
@click.command()
@click.option('--password', prompt=True, hide_input=True, confirmation_prompt=True)
def encrypt(password):
click.echo('Encrypting password to %s' % generate_password_hash(password))
if __name__ == '__main__':
encrypt()
運行結(jié)果:

示例 5 在編輯器中編輯輸入的數(shù)據(jù)
熟悉 Linux 系統(tǒng)的用戶,很可能使用過命令 fc,在編輯長命令時非常便捷。輸入 fc 命令并回車會打開一個編輯器,改編輯器已經(jīng)保存了上一條命令的內(nèi)容。我們只需要在編輯器中修復(fù)錯誤內(nèi)容,然后保存并退出,剛才編輯的命令將會自動執(zhí)行。

使用 Click 庫,在 Python 中也能實現(xiàn)類似的功能:
from __future__ import print_function
import click
import os
message = click.edit()
print(message)
print(os.system(message))
運行代碼,程序?qū)⒆詣舆M入默認編輯器。進入編輯器之后,就可以在編輯器中編輯輸入的數(shù)據(jù),輸入的內(nèi)容將被賦值給程序中的變量 message:

注:Click 是一個非常優(yōu)秀的開源項目,更多詳細用法,可以參見 Click 官網(wǎng):https://click.palletsprojects.com/en/8.0.x/