文中涉及的示例代碼,已同步更新到 HelloGitHub-Team 倉庫python
在上一篇文章中,咱們初步掌握了 click
的簡單用法,並瞭解到它與 argparse
和 docopt
的不一樣。接下來,將深刻介紹 click
的各種用法,以讓你能輕鬆打造複雜的命令行程序。git
在概念上, click
把命令行分爲 3 個組成:參數、選項和命令。github
參數
就是跟在命令後的除選項外的內容,好比 git add a.txt
中的 a.txt
就是表示文件路徑的參數選項
就是以 -
或 --
開頭的參數,好比 -f
、--file
命令
就是命令行的初衷了,好比 git
就是命令,而 git add
中的 add
則是 git
的子命令本系列文章默認使用 Python 3 做爲解釋器進行講解。
若你仍在使用 Python 2,請注意二者之間語法和庫的使用差別哦~
複製代碼
基本參數
就是經過位置裏指定參數值。編程
好比,咱們能夠指定兩個位置參數 x
和 y
,先添加的 x
位於第一個位置,後加入的 y
位於第二個位置。那麼在命令行中輸入 1 2
的時候,分別對應到的就是 x
和 y
:bash
@click.command()
@click.argument('x')
@click.argument('y')
def hello(x, y):
print(x, y)
複製代碼
參數類型
就是將參數值做爲何類型去解析,默認狀況下是字符串類型。咱們能夠經過 type
入參來指定參數類型。ui
click
支持的參數類型多種多樣:spa
str
/ click.STRING
表示字符串類型,這也是默認類型int
/ click.INT
表示整型float
/ click.FLOAT
表示浮點型bool
/ click.BOOL
表示布爾型。很棒之處在於,它會識別表示真/假的字符。對於 1
、yes
、y
和 true
會轉化爲 True
;0
、no
、n
和 false
會轉化爲 False
click.UUID
表示 UUID,會自動將參數轉換爲 uuid.UUID
對象click.FILE
表示文件,會自動將參數轉換爲文件對象,並在命令行結束時自動關閉文件click.PATH
表示路徑click.Choice
表示選擇選項click.IntRange
表示範圍選項同 argparse
同樣,click
也支持自定義類型,須要編寫 click.ParamType
的子類,並重載 convert
方法。命令行
官網提供了一個例子,實現了一個整數類型,除了普通整數以外,還接受十六進制和八進制數字, 並將它們轉換爲常規整數:code
class BasedIntParamType(click.ParamType):
name = "integer"
def convert(self, value, param, ctx):
try:
if value[:2].lower() == "0x":
return int(value[2:], 16)
elif value[:1] == "0":
return int(value, 8)
return int(value, 10)
except TypeError:
self.fail(
"expected string for int() conversion, got "
f"{value!r} of type {type(value).__name__}",
param,
ctx,
)
except ValueError:
self.fail(f"{value!r} is not a valid integer", param, ctx)
BASED_INT = BasedIntParamType()
複製代碼
在基本參數的基礎上,經過指定參數類型,咱們就能構建出各種參數。orm
文件參數
是很是經常使用的一類參數,經過 type=click.File
指定,它能正確處理全部 Python 版本的 unicode 和 字節,使得處理文件十分方便。
@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) # 此時 input 爲文件對象,每次讀入 1024 字節
if not chunk:
break
output.write(chunk) # 此時 output 爲文件對象,寫入上步讀入的內容
複製代碼
文件路徑參數
用來處理文件路徑,能夠對路徑作是否存在等檢查,經過 type=click.Path
指定。不論文件名是 unicode 仍是字節類型,獲取到的參數類型都是 unicode 類型。
@click.command()
@click.argument('filename', type=click.Path(exists=True)) # 要求給定路徑存在,不然報錯
def hello(filename):
click.echo(click.format_filename(filename))
複製代碼
若是文件名是以 -
開頭,會被誤認爲是命令行選項,這個時候須要在參數前加上 --
和空格,好比
$ python hello.py -- -foo.txt
-foo.txt
複製代碼
選擇項參數
用來限定參數內容,經過 type=click.Choice
指定。
好比,指定文件讀取方式限制爲 read-only
和 read-write
:
@click.command()
@click.argument('mode', type=click.Choice(['read-only', 'read-write']))
def hello(mode):
click.echo(mode)
複製代碼
可變參數
用來定義一個參數能夠有多個值,且能經過 nargs
來定義值的個數,取得的參數的變量類型爲元組。
若 nargs=N
,N
爲一個數字,則要求該參數提供 N 個值。若 N
爲 -1
則接受提供無數量限制的參數,如:
@click.command()
@click.argument('foo', nargs=-1)
@click.argument('bar', nargs=1)
def hello(foo, bar):
pass
複製代碼
若是要實現 argparse
中要求參數數量爲 1 個或多個的功能,則指定 nargs=-1
且 required=True
便可:
@click.command()
@click.argument('foo', nargs=-1, required=True)
def hello(foo, bar):
pass
複製代碼
經過在 click.argument
中指定 envvar
,則可讀取指定名稱的環境變量做爲參數值,好比:
@click.command()
@click.argument('filename', envvar='FILENAME')
def hello(filename):
print(filename)
複製代碼
執行以下命令查看效果:
$ FILENAME=hello.txt python3 hello.py
hello.txt
複製代碼
而在 argparse
中,則須要本身從環境變量中讀取。
本文講解了 click
中基本參數的用法,在此基礎上介紹了各類類型的參數,最後說明了從環境變量中獲取參數值的寫法。
在下一篇文章中,咱們來繼續深刻了解 click
的功能,看看它都支持什麼樣的「選項」。
『講解開源項目系列』——讓對開源項目感興趣的人再也不畏懼、讓開源項目的發起者再也不孤單。跟着咱們的文章,你會發現編程的樂趣、使用和發現參與開源項目如此簡單。歡迎留言聯繫咱們、加入咱們,讓更多人愛上開源、貢獻開源~