Python——click模块
Click?是?Flask?的開(kāi)發(fā)團(tuán)隊(duì)?Pallets?的另一款開(kāi)源項(xiàng)目,它是用于快速創(chuàng)建命令行的第三方模塊。
我們知道,Python 內(nèi)置了一個(gè)?Argparse?的標(biāo)準(zhǔn)庫(kù)用于創(chuàng)建命令行,但使用起來(lái)有些繁瑣,Click?相比于?Argparse,就好比?requests?相比于?urllib。
Click?是一個(gè)第三方庫(kù),因此,在使用之前需要先安裝:
| 1 | pip?install?click |
參考文檔http://click.pocoo.org/6/options/
Click 對(duì)argparse 的主要改進(jìn)在易用性,使用Click 分為兩個(gè)步驟:
看一下官方文檔的入門例子:
import click@click.command() @click.option('--count', default=1, help='Number of greetings.') @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 有兩個(gè)參數(shù):count 和 name,它們的值從命令行中獲取。
?
-
@click.command() 使函數(shù) hello 成為命令行接口;
-
@click.option 的第一個(gè)參數(shù)指定了命令行選項(xiàng)的名稱,可以看到,count 的默認(rèn)值是 1;
-
使用 click.echo 進(jìn)行輸出是為了獲得更好的兼容性,因?yàn)?print 在 Python2 和 Python3 的用法有些差別。
?
執(zhí)行情況
$ python hello.py Your name: Ethan # 這里會(huì)顯示 'Your name: '(對(duì)應(yīng)代碼中的 prompt),接受用戶輸入 Hello Ethan!$ python hello.py --help # click 幫我們自動(dòng)生成了 `--help` 用法 Usage: hello.py [OPTIONS]Simple program that greets NAME for a total of COUNT times.Options:--count INTEGER Number of greetings.--name TEXT The person to greet.--help Show this message and exit.$ python hello.py --count 3 --name Ethan # 指定 count 和 name 的值 Hello Ethan! Hello Ethan! Hello Ethan!$ python hello.py --count=3 --name=Ethan # 也可以使用 `=`,和上面等價(jià) Hello Ethan! Hello Ethan! Hello Ethan!$ python hello.py --name=Ethan # 沒(méi)有指定 count,默認(rèn)值是 1 Hello Ethan!?
回到頂部
Group使用
Click 通過(guò) group 來(lái)創(chuàng)建一個(gè)命令行組,也就是說(shuō)它可以有各種參數(shù)來(lái)解決相同類別的不同問(wèn)題
import click@click.group() def cli():pass@click.command() def initdb():click.echo('Initialized the database') ···· @click.command() def dropdb():click.echo('Droped the database')cli.add_command(initdb) cli.add_command(dropdb)if __name__ == "__main__":cli()執(zhí)行情況
$ python hello.py Usage: hello.py [OPTIONS] COMMAND [ARGS]...Options:--help Show this message and exit.Commands:dropdbinitdb $ python hello.py initdb Initialized the database $ python hello.py dropdb Droped the database?
?
?click.option使用
option 最基本的用法就是通過(guò)指定命令行選項(xiàng)的名稱,從命令行讀取參數(shù)值,再將其傳遞給函數(shù)。
在上面的例子,我們看到,除了設(shè)置命令行選項(xiàng)的名稱,我們還會(huì)指定默認(rèn)值,help 說(shuō)明等,option 常用的設(shè)置參數(shù)如下:
?
-
default: 設(shè)置命令行參數(shù)的默認(rèn)值
-
help: 參數(shù)說(shuō)明
-
type: 參數(shù)類型,可以是 string, int, float 等
-
prompt: 當(dāng)在命令行中沒(méi)有輸入相應(yīng)的參數(shù)時(shí),會(huì)根據(jù) prompt 提示用戶輸入
-
nargs: 指定命令行參數(shù)接收的值的個(gè)數(shù)
-
metavar:如何在幫助頁(yè)面表示值
?
下面,我們?cè)倏纯聪嚓P(guān)的例子。
指定 type
我們可以使用 type 來(lái)指定參數(shù)類型:
import click@click.command() @click.option('--rate', type=float, help='rate') # 指定 rate 是 float 類型 def show(rate):click.echo('rate: %s' % rate)if __name__ == '__main__':show()?
?執(zhí)行情況:
$ python click_type.py --help Usage: click_type.py [OPTIONS]Options:--rate FLOAT rate--help Show this message and exit.$ python click_type.py --rate 1 rate: 1.0 $ python click_type.py --rate 0.66 rate: 0.66?
可選值
在某些情況下,一個(gè)參數(shù)的值只能是某些可選的值,如果用戶輸入了其他值,我們應(yīng)該提示用戶輸入正確的值。
在這種情況下,我們可以通過(guò) click.Choice() 來(lái)限定
執(zhí)行情況:
$ python click_choice.py --help Usage: click_choice.py [OPTIONS]Options:--gender [man|woman]--help Show this message and exit.$ python click_choice.py --gender boy Usage: click_choice.py [OPTIONS]Error: Invalid value for "--gender": invalid choice: boy. (choose from man, woman)$ python click_choice.py --gender man gender: man?
多值參數(shù)
有時(shí),一個(gè)參數(shù)需要接收多個(gè)值。option?支持設(shè)置固定長(zhǎng)度的參數(shù)值,通過(guò)?nargs?指定。
$ python click_multi_values.py --help Usage: click_multi_values.py [OPTIONS]Options:--center FLOAT... center of the circle--radius FLOAT radius of the circle$ python click_multi_values.py --center 3 4 --radius 10 center: (3.0, 4.0), radius: 10.0$ python click_multi_values.py --center 3 4 5 --radius 10 Usage: click_multi_values.py [OPTIONS]Error: Got unexpected extra argument (5)?
輸入密碼
?有時(shí),在輸入密碼的時(shí)候,我們希望能隱藏顯示。option 提供了兩個(gè)參數(shù)來(lái)設(shè)置密碼的輸入:
hide_input 和 confirmation_promt,其中,hide_input 用于隱藏輸入,confirmation_promt 用于重復(fù)輸入。
import click@click.command() @click.option('--password', prompt=True, hide_input=True, confirmation_prompt=True) def input_password(password):click.echo('password: %s' % password)if __name__ == '__main__':input_password()?
執(zhí)行情況:
$ python click_password.py Password: # 不會(huì)顯示密碼 Repeat for confirmation: # 重復(fù)一遍 password: 123click 也提供了一種快捷的方式,通過(guò)使用 @click.password_option(),上面的代碼可以簡(jiǎn)寫(xiě)成:
import click@click.command() @click.password_option() def input_password(password):click.echo('password: %s' % password)if __name__ == '__main__':input_password()?click.IntRange()
@click.command() @click.option('--count', type=click.IntRange(0, 20, clamp=True)) @click.option('--digit', type=click.IntRange(0, 10)) def repeat(count, digit):click.echo(str(digit) * count)if __name__ == '__main__':repeat()========================================= $ repeat --count=1000 --digit=5 55555555555555555555 $ repeat --count=1000 --digit=12 Usage: repeat [OPTIONS]Error: Invalid value for "--digit": 12 is not in the valid range of 0 to 10.?
?
改變命令行程序的執(zhí)行
?有些參數(shù)會(huì)改變命令行程序的執(zhí)行,比如在終端輸入 python 是進(jìn)入 python 控制臺(tái),
而輸入 python --version 是打印 python 版本。Click 提供 eager 標(biāo)識(shí)對(duì)參數(shù)名進(jìn)行標(biāo)識(shí),
如果輸入該參數(shù),則會(huì)攔截既定的命令行執(zhí)行流程,跳轉(zhuǎn)去執(zhí)行一個(gè)回調(diào)函數(shù)。
import click def print_version(ctx, param, value):if not value or ctx.resilient_parsing:returnclick.echo('Version 1.0')ctx.exit() @click.command() @click.option('--version', is_flag=True, callback=print_version,expose_value=False, is_eager=True) @click.option('--name', default='Ethan', help='name') def hello(name):click.echo('Hello %s!' % name) if __name__ == '__main__':hello()?
其中:
- is_eager=True?表明該命令行選項(xiàng)優(yōu)先級(jí)高于其他選項(xiàng);
- expose_value=False?表示如果沒(méi)有輸入該命令行選項(xiàng),會(huì)執(zhí)行既定的命令行流程;
- callback?指定了輸入該命令行選項(xiàng)時(shí),要跳轉(zhuǎn)執(zhí)行的函數(shù)
- is_flag=True 表明參數(shù)值可以省略
執(zhí)行情況:
$ python click_eager.py Hello Ethan! $ python click_eager.py --version # 攔截既定的命令行執(zhí)行流程 Version 1.0 $ python click_eager.py --name Michael Hello Michael! $ python click_eager.py --version --name Ethan # 忽略 name 選項(xiàng) Version 1.0?
使用argument
我們除了使用?@click.option?來(lái)添加可選參數(shù),還會(huì)經(jīng)常使用?@click.argument?來(lái)添加固定參數(shù)。
它的使用和 option 類似,但支持的功能比 option 少。
入門使用
下面是一個(gè)簡(jiǎn)單的例子:
import click @click.command() @click.argument('coordinates') def show(coordinates):click.echo('coordinates: %s' % coordinates) if __name__ == '__main__':show()看看執(zhí)行情況:
$ python click_argument.py # 錯(cuò)誤,缺少參數(shù) coordinates Usage: click_argument.py [OPTIONS] COORDINATES Error: Missing argument "coordinates". $ python click_argument.py --help # argument 指定的參數(shù)在 help 中沒(méi)有顯示 Usage: click_argument.py [OPTIONS] COORDINATES Options:--help Show this message and exit. $ python click_argument.py --coordinates 10 # 錯(cuò)誤用法,這是 option 參數(shù)的用法 Error: no such option: --coordinates $ python click_argument.py 10 # 正確,直接輸入值即可 coordinates: 10?
多個(gè) argument
import click @click.command() @click.argument('x') @click.argument('y') @click.argument('z') def show(x, y, z):click.echo('x: %s, y: %s, z:%s' % (x, y, z)) if __name__ == '__main__':show()執(zhí)行情況
$ python click_argument.py 10 20 30 x: 10, y: 20, z:30 $ python click_argument.py 10 Usage: click_argument.py [OPTIONS] X Y Z Error: Missing argument "y". $ python click_argument.py 10 20 Usage: click_argument.py [OPTIONS] X Y Z Error: Missing argument "z". $ python click_argument.py 10 20 30 40 Usage: click_argument.py [OPTIONS] X Y Z Error: Got unexpected extra argument (40)?
不定參數(shù)
argument 還有另外一種常見(jiàn)的用法,就是接收不定量的參數(shù),讓我們看看例子:
import click @click.command() @click.argument('src', nargs=-1) @click.argument('dst', nargs=1) def move(src, dst):click.echo('move %s to %s' % (src, dst)) if __name__ == '__main__':move()?
其中,nargs=-1?表明參數(shù)?src?接收不定量的參數(shù)值,參數(shù)值會(huì)以 tuple 的形式傳入函數(shù)。
如果?nargs?大于等于 1,表示接收?nargs?個(gè)參數(shù)值,上面的例子中,dst?接收一個(gè)參數(shù)值。
執(zhí)行情況:
$ python click_argument.py file1 trash # src=('file1',) dst='trash' move ('file1',) to trash $ python click_argument.py file1 file2 file3 trash # src=('file1', 'file2', 'file3') dst='trash' move ('file1', 'file2', 'file3') to trash?
Click 支持通過(guò)文件名參數(shù)對(duì)文件進(jìn)行操作,click.File() 裝飾器就是處理這種操作的,尤其是在類 Unix 系統(tǒng)下,它支持以 - 符號(hào)作為標(biāo)準(zhǔn)輸入/輸出?
# File @click.command() @click.argument('input', type=click.File('rb')) @click.argument('output', type=click.File('wb')) def inout(input, output):while True:chunk = input.read(1024)if not chunk:breakoutput.write(chunk)?
彩色輸出
在前面的例子中,我們使用?click.echo?進(jìn)行輸出,如果配合?colorama?這個(gè)模塊,
我們可以使用?click.secho?進(jìn)行彩色輸出,在使用之前,使用 pip 安裝 colorama:
| 1 | $ pip install colorama |
例子:
import click @click.command() @click.option('--name', help='The person to greet.') def hello(name):click.secho('Hello %s!' % name, fg='red', underline=True)click.secho('Hello %s!' % name, fg='yellow', bg='black') if __name__ == '__main__':hello()?
其中:
- fg?表示前景顏色(即字體顏色),可選值有:BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE 等;
- bg?表示背景顏色,可選值有:BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE 等;
- underline?表示下劃線,可選的樣式還有:dim=True,bold=True?等;
?
Click 通過(guò) click.option() 添加可選參數(shù),通過(guò) click.argument() 來(lái)添加有可能可選的參數(shù)
以下幾點(diǎn)是兩個(gè)的區(qū)別:
- 需要提示補(bǔ)全輸入的時(shí)候使用 option()
- 標(biāo)志位(flag or acts) 使用 option()
- option的值可以從環(huán)境變量獲取,而argument不行
- option的值會(huì)在幫助里面列出,而argument不能
?
安裝打包
Click 支持使用?setuptools?來(lái)更好的實(shí)現(xiàn)命令行程序打包,把源碼文件打包成系統(tǒng)中的可執(zhí)行程序,
并且不限平臺(tái)。一般我們會(huì)在源碼根目錄下創(chuàng)建?setup.py?腳本,先看一段簡(jiǎn)單的打包代碼
from setuptools import setupsetup(name='hello',version='0.1',py_modules=['hello'],install_requires=['Click',],entry_points={'console_scripts': ['digest=hello:digest','goodbye=hello:goodbye']}, )?
hello.py
默認(rèn)情況下click不提供-h。需要使用context_settings參數(shù)來(lái)重寫(xiě)默認(rèn)help_option_names。
import clickCONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])def greeter(**kwargs):output = '{0}, {1}!'.format(kwargs['greeting'],kwargs['name'])if kwargs['caps']:output = output.upper()print(output)@click.group(context_settings=CONTEXT_SETTINGS) @click.version_option(version='1.0.0') def greet():pass@greet.command() @click.argument('name') @click.option('--greeting', default='Hello', help='word to use for the greeting') @click.option('--caps', is_flag=True, help='uppercase the output') def hello(**kwargs):greeter(**kwargs)@greet.command() @click.argument('name') @click.option('--greeting', default='Goodbye', help='word to use for the greeting') @click.option('--caps', is_flag=True, help='uppercase the output') def goodbye(**kwargs):greeter(**kwargs)@greet.command() @click.option('--hash-type', type=click.Choice(['md5', 'sha1'])) def digest(hash_type):click.echo(hash_type)if __name__ == '__main__':greet()?執(zhí)行情況
#python hello.py install # digest --hash-type md5 md5# goodbye --help Usage: goodbye [OPTIONS] NAMEOptions:--greeting TEXT word to use for the greeting--caps uppercase the output--help Show this message and exit. # goodbye --caps hh GOODBYE, HH!舉例說(shuō)明
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | import?click ? CONTEXT_SETTINGS?=?dict(help_option_names=['-h',?'--help']) ? ? @click.group(context_settings=CONTEXT_SETTINGS) @click.version_option(version='1.0.0') def?cli(): ????"""Repo is a command line tool that showcases how to build complex ????????command line interfaces with Click. ????????This tool is supposed to look like a distributed version control ????????system to show how something like this can be structured. ????)""" ????pass ? ? @cli.command() @click.argument('name', default='all', required=True) # @click.option('--greeting', default='Hello', help='word to use for the greeting') # @click.option('--caps', is_flag=True, help='uppercase the output') def?hellocmd(name): ????click.echo( ????????click.style( ????????????'I am colored %s and bold'?% ????????????name, ????????????fg='green', ????????????bold=True)) ? ? @cli.command() @click.option('-t', default='a', required=True, ??????????????type=click.Choice(['a',?'h']), prompt=True,?help='檢查磁盤(pán)空間,a表示所有空間,h表示空間大于50%') def?dfcmd(t): ????""" ????檢查磁盤(pán)空間 dfcmd ????:param t: ????:return: ????""" ????click.echo(click.style('檢查磁盤(pán)空間', fg='green', bold=True)) ? ? @cli.command(context_settings=CONTEXT_SETTINGS) @click.argument('x',?type=int, required=True) def?square(x): ????""" ????得到x平方 square x ????""" ????click.echo(click.style('x= %s'?%?x, fg='green', bold=True)) ????print(x?*?x) ? ? if?__name__?==?'__main__': ????cli() |
輸出結(jié)果
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | XXXPycharmProjects\LuffyFTP\utils>python arg_example.py Usage: arg_example.py [OPTIONS] COMMAND [ARGS]... ? ??Repo?is?a command line tool that showcases how to build?complex ??command line interfaces with Click.???? This tool?is?supposed to look like ??a distributed version control???? system to show how something like this ??can be structured. ) ? Options: ??--version?? Show the version?and?exit. ??-h,?--help??Show this message?and?exit. ? Commands: ??dfcmd???? 檢查磁盤(pán)空間 dfcmd :param t: :return: ??hellocmd ??square??? 得到x平方 square x ? XXXPycharmProjects\LuffyFTP\utils>python arg_example.py?-h Usage: arg_example.py [OPTIONS] COMMAND [ARGS]... ? ??Repo?is?a command line tool that showcases how to build?complex ??command line interfaces with Click.???? This tool?is?supposed to look like ??a distributed version control???? system to show how something like this ??can be structured. ) ? Options: ??--version?? Show the version?and?exit. ??-h,?--help??Show this message?and?exit. ? Commands: ??dfcmd???? 檢查磁盤(pán)空間 dfcmd :param t: :return: ??hellocmd ??square??? 得到x平方 square x ? XXXPycharmProjects\LuffyFTP\utils>python arg_example.py dfcmd?-h Usage: arg_example.py dfcmd [OPTIONS] ? ??檢查磁盤(pán)空間 dfcmd :param t: :return: ? Options: ??-t [a|h]??? 檢查磁盤(pán)空間,a表示所有空間,h表示空間大于50%??[required] ??-h,?--help??Show this message?and?exit. ? XXXPycharmProjects\LuffyFTP\utils>python arg_example.py square?-h ? Usage: arg_example.py square [OPTIONS] X ? ??得到x平方 square x ? Options: ??-h,?--help??Show this message?and?exit. ? XXXPycharmProjects\LuffyFTP\utils>python arg_example.py square?5 x5 25 ? XXXPycharmProjects\LuffyFTP\utils>python arg_example.py square?5 x=?5 25 |
總結(jié)
以上是生活随笔為你收集整理的Python——click模块的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ai条码插件免安装_AI条码插件Barc
- 下一篇: python3 打点计时