程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python 命令行參數:Argparse 與 Click

編輯:Python

Python 命令行參數:Argparse 與 Click

      • 簡介
      • 一、Argparse 模塊
        • 1.1 概念
        • 1.2 基礎
        • 1.3 位置參數介紹
        • 1.4 可選參數介紹
        • 1.5 短選項
        • 1.6 結合位置參數和可選參數
        • 1.7 進行一些小小的改進
        • 1.8 矛盾的選項
      • 二、Click 模塊
        • 2.1 Click
        • 2.2 group 使用
        • 2.3 click.option 使用
        • 2.3.1 type
          • 2.3.2 可選值
          • 2.3.3 多值參數
          • 2.3.4 輸入密碼
        • 2.4 click.IntRange()
        • 2.5 改變命令行程序的執行
      • 後記

作者:高玉涵
時間:2022.7.29 10:15
博客:blog.csdn.net/cg_i

簡介

和以往一樣,我在實踐過程中,執行編寫的程序時,通過命令行傳值給 Python 程序,達到從外部控制程序(而不是在代碼內對這些值進行硬編碼)。Python 內置了 Argparse 的標准庫用於創建命令行,但使用起來有些繁瑣。Click 是用 Python 寫的一個第三方模塊,用於快速創建命令行。如果你是第一次聽說這兩個模塊,不必困惑做為對比,下面都將給出它們使用方法,便於你理解它們的差異。

注解: 還有另外兩個模塊可以完成同樣的任務,稱為 getopt (對應於 C 語言中的 getopt() 函數) 和被棄用的 optparse。還要注意 argparse 是基於 optparse 的,因此用法與其非常相似。

一、Argparse 模塊

1.1 概念

讓我們利用 ls 命令來展示我們將要在這篇入門教程中探索的功能:

$ ls
cpython devguide prog.py pypy rm-unused-function.patch
$ ls pypy
ctypes_configure demo dotviewer include lib_pypy lib-python ...
$ ls -l
total 20
drwxr-xr-x 19 wena wena 4096 Feb 18 18:51 cpython
drwxr-xr-x 4 wena wena 4096 Feb 8 12:04 devguide
-rwxr-xr-x 1 wena wena 535 Feb 19 00:05 prog.py
drwxr-xr-x 14 wena wena 4096 Feb 7 00:59 pypy
-rw-r--r-- 1 wena wena 741 Feb 18 01:01 rm-unused-function.patch
$ ls --help
Usage: ls [OPTION]... [FILE]...
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.
...

我們可以從這四個命令中學到幾個概念:

  • ls 是一個即使在運行的時候沒有提供任何選項,也非常有用的命令。在默認情況下他會輸出當前文件夾包含的文件和文件夾。

  • 如果我們想要使用比它默認提供的更多功能,我們需要告訴該命令更多信息。在這個例子裡,我們想要查看一個不同的目錄,pypy。我們所做的是指定所謂的位置參數。之所以這樣命名,是因為程序應該如何處理該參數值,完全取決於它在命令行出現的位置。更能體現這個概念的命令如 cp,它最基本的用法是 cp SRC DEST。第一個位置參數指的是你想要復制的,第二個位置參數指的是你想要復制到的位置

  • 現在假設我們想要改變這個程序的行為。在我們的例子中,我們不僅僅只是輸出每個文件的文件名,還輸出了更多信息。在這個例子中,-l 被稱為可選參數。

  • 這是一段幫助文檔的文字。它是非常有用的,因為當你遇到一個你從未使用過的程序時,你可以通過閱讀它的幫助文檔來弄清楚它是如何運行的。

1.2 基礎

讓我們從一個簡單到(幾乎)什麼也做不了的例子開始:

import argparse
parser = argparse.ArgumentParser()
parser.parse_args()
以下是該代碼的運行結果:
$ python3 prog.py
$ python3 prog.py --help
usage: prog.py [-h]
options:
-h, --help show this help message and exit
$ python3 prog.py --verbose
usage: prog.py [-h]
prog.py: error: unrecognized arguments: --verbose
$ python3 prog.py foo
usage: prog.py [-h]
prog.py: error: unrecognized arguments: foo

程序運行情況如下:

  • 在沒有任何選項的情況下運行腳本不會在標准輸出顯示任何內容。這沒有什麼用處。

  • 第二行代碼開始展現出 argparse 模塊的作用。我們幾乎什麼也沒有做,但已經得到一條很好的幫助信息。

  • --help 選項,也可縮寫為 -h,是唯一一個可以直接使用的選項(即不需要指定該選項的內容)。指定任何內容都會導致錯誤。即便如此,我們也能直接得到一條有用的用法信息。

1.3 位置參數介紹

舉個例子:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("echo")
args = parser.parse_args()
print(args.echo)

運行此程序:

$ python3 prog.py
usage: prog.py [-h] echo
prog.py: error: the following arguments are required: echo
$ python3 prog.py --help
usage: prog.py [-h] echo
positional arguments:
echo
options:
-h, --help show this help message and exit
$ python3 prog.py foo
foo

程序運行情況如下:

  • 我們增加了 add_argument() 方法,該方法用於指定程序能夠接受哪些命令行選項。在這個例子中,我將選項命名為 echo,與其功能一致。

  • 現在調用我們的程序必須要指定一個選項。

  • The parse_args() method actually returns some data from the options specified, in this case, echo.

  • 這一變量是 argparse 免費施放的某種 “魔法”(即是說,不需要指定哪個變量是存儲哪個值的)。你也可以注意到,這一名稱與傳遞給方法的字符串參數一致,都是 echo

然而請注意,盡管顯示的幫助看起來清楚完整,但它可以比現在更有幫助。比如我們可以知道 echo 是一個位置參數,但我們除了靠猜或者看源代碼,沒法知道它是用來干什麼的。所以,我們可以把它改造得更有用:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("echo", help="echo the string you use here")
args = parser.parse_args()
print(args.echo)

然後我們得到:

$ python3 prog.py -h
usage: prog.py [-h] echo
positional arguments:
echo echo the string you use here
options:
-h, --help show this help message and exit

現在,來做一些更有用的事情:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", help="display a square of a given number")
args = parser.parse_args()
print(args.square**2)

以下是該代碼的運行結果:

$ python3 prog.py 4
Traceback (most recent call last):
File "prog.py", line 5, in <module>
print(args.square**2)
TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'

進展不太順利。那是因為 argparse 會把我們傳遞給它的選項視作為字符串,除非我們告訴它別這樣。所以,讓我們來告訴 argparse 來把這一輸入視為整數:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", help="display a square of a given number",
type=int)
args = parser.parse_args()
print(args.square**2)

以下是該代碼的運行結果:

$ python3 prog.py 4
16
$ python3 prog.py four
usage: prog.py [-h] square
prog.py: error: argument square: invalid int value: 'four'

做得不錯。當這個程序在收到錯誤的無效的輸入時,它甚至能在執行計算之前先退出,還能顯示很有幫助的錯誤信息。

1.4 可選參數介紹

到目前為止,我們一直在研究位置參數。讓我們看看如何添加可選的:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--verbosity", help="increase output verbosity")
args = parser.parse_args()
if args.verbosity:
print("verbosity turned on")

和輸出:

$ python3 prog.py --verbosity 1
verbosity turned on
$ python3 prog.py
$ python3 prog.py --help
usage: prog.py [-h] [--verbosity VERBOSITY]
options:
-h, --help show this help message and exit
--verbosity VERBOSITY
increase output verbosity
$ python3 prog.py --verbosity
usage: prog.py [-h] [--verbosity VERBOSITY]
prog.py: error: argument --verbosity: expected one argument

程序運行情況如下:

  • 這一程序被設計為當指定 --verbosity 選項時顯示某些東西,否則不顯示。

  • 不添加這一選項時程序沒有提示任何錯誤而退出,表明這一選項確實是可選的。注意,如果一個可選參數沒有被使用時,相關變量被賦值為 None,在此例中是 args.verbosity,這也就是為什麼它在 if 語句中被當作邏輯假。

  • 幫助信息有點不同。

  • 使用 --verbosity 選項時,必須指定一個值,但可以是任何值。

上述例子接受任何整數值作為 --verbosity 的參數,但對於我們的簡單程序而言,只有兩個值有實際意義:True 或者 False。讓我們據此修改代碼:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--verbose", help="increase output verbosity",
action="store_true")
args = parser.parse_args()
if args.verbose:
print("verbosity turned on")

和輸出:

$ python3 prog.py --verbose
verbosity turned on
$ python3 prog.py --verbose 1
usage: prog.py [-h] [--verbose]
prog.py: error: unrecognized arguments: 1
$ python3 prog.py --help
usage: prog.py [-h] [--verbose]
options:
-h, --help show this help message and exit
--verbose increase output verbosity

程序運行情況如下:

  • 現在,這一選項更多地是一個標志,而非需要接受一個值的什麼東西。我們甚至改變了選項的名字來符合這一思路。注意我們現在指定了一個新的關鍵詞 action,並賦值為 "store_true"。這意味著,當這一選項存在時,為 args.verbose 賦值為 True。沒有指定時則隱含地賦值為 False

  • 當你為其指定一個值時,它會報錯,符合作為標志的真正的精神。

  • 留意不同的幫助文字。

1.5 短選項

如果你熟悉命令行的用法,你會發現我還沒講到這一選項的短版本。這也很簡單:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-v", "--verbose", help="increase output verbosity",
action="store_true")
args = parser.parse_args()
if args.verbose:
print("verbosity turned on")

效果就像這樣:

$ python3 prog.py -v
verbosity turned on
$ python3 prog.py --help
usage: prog.py [-h] [-v]
options:
-h, --help show this help message and exit
-v, --verbose increase output verbosity

可以注意到,這一新的能力也反映在幫助文本裡。

1.6 結合位置參數和可選參數

我們的程序變得越來越復雜了:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
help="display a square of a given number")
parser.add_argument("-v", "--verbose", action="store_true",
help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbose:
print(f"the square of {args.square} equals {answer}")
else:
print(answer)

接著是輸出:

$ python3 prog.py
usage: prog.py [-h] [-v] square
prog.py: error: the following arguments are required: square
$ python3 prog.py 4
16
$ python3 prog.py 4 --verbose
the square of 4 equals 16
$ python3 prog.py --verbose 4
the square of 4 equals 16
  • 我們帶回了一個位置參數,結果發生了報錯。

  • 注意順序無關緊要。

給我們的程序加上接受多個冗長度的值,然後實際來用用:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
help="display a square of a given number")
parser.add_argument("-v", "--verbosity", type=int,
help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbosity == 2:
print(f"the square of {args.square} equals {answer}")
elif args.verbosity == 1:
print(f"{args.square}^2 == {answer}")
else:
print(answer)

和輸出:

$ python3 prog.py 4
16
$ python3 prog.py 4 -v
usage: prog.py [-h] [-v VERBOSITY] square
prog.py: error: argument -v/--verbosity: expected one argument
$ python3 prog.py 4 -v 1
4^2 == 16
$ python3 prog.py 4 -v 2
the square of 4 equals 16
$ python3 prog.py 4 -v 3
16

除了最後一個,看上去都不錯。最後一個暴露了我們的程序中有一個 bug。我們可以通過限制 --verbosity 選項可以接受的值來修復它:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
help="display a square of a given number")
parser.add_argument("-v", "--verbosity", type=int, choices=[0, 1, 2],
help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbosity == 2:
print(f"the square of {args.square} equals {answer}")
elif args.verbosity == 1:
print(f"{args.square}^2 == {answer}")
else:
print(answer)

和輸出:

$ python3 prog.py 4 -v 3
usage: prog.py [-h] [-v {0,1,2}] square
prog.py: error: argument -v/--verbosity: invalid choice: 3 (choose from 0, 1, 2)
$ python3 prog.py 4 -h
usage: prog.py [-h] [-v {0,1,2}] square
positional arguments:
square display a square of a given number
options:
-h, --help show this help message and exit
-v {0,1,2}, --verbosity {0,1,2}
increase output verbosity

注意這一改變同時反應在錯誤信息和幫助信息裡。

現在,讓我們使用另一種的方式來改變冗長度。這種方式更常見,也和 CPython 的可執行文件處理它自己的冗長度參數的方式一致(參考 python --help 的輸出):

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
help="display the square of a given number")
parser.add_argument("-v", "--verbosity", action="count",
help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbosity == 2:
print(f"the square of {args.square} equals {answer}")
elif args.verbosity == 1:
print(f"{args.square}^2 == {answer}")
else:
print(answer)

我們引入了另一種動作 “count”,來統計特定選項出現的次數。

$ python3 prog.py 4
16
$ python3 prog.py 4 -v
4^2 == 16
$ python3 prog.py 4 -vv
the square of 4 equals 16
$ python3 prog.py 4 --verbosity --verbosity
the square of 4 equals 16
$ python3 prog.py 4 -v 1
usage: prog.py [-h] [-v] square
prog.py: error: unrecognized arguments: 1
$ python3 prog.py 4 -h
usage: prog.py [-h] [-v] square
positional arguments:
square display a square of a given number
options:
-h, --help show this help message and exit
-v, --verbosity increase output verbosity
$ python3 prog.py 4 -vvv
16
  • 是的,它現在比前一版本更像是一個標志(和 action="store_true" 相似)。這能解釋它為什麼報錯。

  • 它也表現得與 “store_true” 的行為相似。

  • 這給出了一個關於 count 動作的效果的演示。你之前很可能應該已經看過這種用法。

  • 如果你不添加 -v 標志,這一標志的值會是 None

  • 如期望的那樣,添加該標志的長形態能夠獲得相同的輸出。

  • 可惜的是,對於我們的腳本獲得的新能力,我們的幫助輸出並沒有提供很多信息,但我們總是可以通過改善文檔來修復這一問題(比如通過 help 關鍵字參數)。

  • 最後一個輸出暴露了我們程序中的一個 bug。

讓我們修復一下:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
help="display a square of a given number")
parser.add_argument("-v", "--verbosity", action="count",
help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
# bugfix: replace == with >=
if args.verbosity >= 2:
print(f"the square of {args.square} equals {answer}")
elif args.verbosity >= 1:
print(f"{args.square}^2 == {answer}")
else:
print(answer)

這是它給我們的輸出:

$ python3 prog.py 4 -vvv
the square of 4 equals 16
$ python3 prog.py 4 -vvvv
the square of 4 equals 16
$ python3 prog.py 4
Traceback (most recent call last):
File "prog.py", line 11, in <module>
if args.verbosity >= 2:
TypeError: '>=' not supported between instances of 'NoneType' and 'int'
  • 第一組輸出很好,修復了之前的 bug。也就是說,我們希望任何 >= 2 的值盡可能詳盡。

  • 第三組輸出並不理想。

讓我們修復那個 bug:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
help="display a square of a given number")
parser.add_argument("-v", "--verbosity", action="count", default=0,
help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbosity >= 2:
print(f"the square of {args.square} equals {answer}")
elif args.verbosity >= 1:
print(f"{args.square}^2 == {answer}")
else:
print(answer)

我們剛剛引入了又一個新的關鍵字 default。我們把它設置為 0 來讓它可以與其他整數值相互比較。記住,默認情況下如果一個可選參數沒有被指定,它的值會是 None,並且它不能和整數值相比較(所以產生了 TypeError 異常)。

然後:

$ python3 prog.py 4
16

憑借我們目前已學的東西你就可以做到許多事情,而我們還僅僅學了一些皮毛而已。 argparse 模塊是非常強大的,在結束篇教程之前我們將再探索更多一些內容。

1.7 進行一些小小的改進

如果我們想擴展我們的簡短程序來執行其他冪次的運算,而不僅是乘方:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("x", type=int, help="the base")
parser.add_argument("y", type=int, help="the exponent")
parser.add_argument("-v", "--verbosity", action="count", default=0)
args = parser.parse_args()
answer = args.x**args.y
if args.verbosity >= 2:
print(f"{args.x} to the power {args.y} equals {answer}")
elif args.verbosity >= 1:
print(f"{args.x}^{args.y} == {answer}")
else:
print(answer)

輸出:

$ python3 prog.py
usage: prog.py [-h] [-v] x y
prog.py: error: the following arguments are required: x, y
$ python3 prog.py -h
usage: prog.py [-h] [-v] x y
positional arguments:
x the base
y the exponent
options:
-h, --help show this help message and exit
-v, --verbosity
$ python3 prog.py 4 2 -v
4^2 == 16

請注意到目前為止我們一直在使用詳細級別來 更改 所顯示的文本。 以下示例則使用詳細級別來顯示 更多的 文本:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("x", type=int, help="the base")
parser.add_argument("y", type=int, help="the exponent")
parser.add_argument("-v", "--verbosity", action="count", default=0)
args = parser.parse_args()
answer = args.x**args.y
if args.verbosity >= 2:
print(f"Running '{__file__}'")
if args.verbosity >= 1:
print(f"{args.x}^{args.y} == ", end="")
print(answer)
輸出:
$ python3 prog.py 4 2
16
$ python3 prog.py 4 2 -v
4^2 == 16
$ python3 prog.py 4 2 -vv
Running 'prog.py'
4^2 == 16

1.8 矛盾的選項

到目前為止,我們一直在使用 argparse.ArgumentParser 實例的兩個方法。 讓我們再介紹第三個方法 add_mutually_exclusive_group()。 它允許我們指定彼此相互沖突的選項。 讓我們再更改程序的其余部分以便使用新功能更有意義:我們將引入 --quiet 選項,它將與 --verbose 正好相反:

import argparse
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument("-v", "--verbose", action="store_true")
group.add_argument("-q", "--quiet", action="store_true")
parser.add_argument("x", type=int, help="the base")
parser.add_argument("y", type=int, help="the exponent")
args = parser.parse_args()
answer = args.x**args.y
if args.quiet:
print(answer)
elif args.verbose:
print(f"{args.x} to the power {args.y} equals {answer}")
else:
print(f"{args.x}^{args.y} == {answer}")

我們的程序現在變得更簡潔了,我們出於演示需要略去了一些功能。 無論如何,輸出是這樣的:

$ python3 prog.py 4 2
4^2 == 16
$ python3 prog.py 4 2 -q
16
$ python3 prog.py 4 2 -v
4 to the power 2 equals 16
$ python3 prog.py 4 2 -vq
usage: prog.py [-h] [-v | -q] x y
prog.py: error: argument -q/--quiet: not allowed with argument -v/--verbose
$ python3 prog.py 4 2 -v --quiet
usage: prog.py [-h] [-v | -q] x y
prog.py: error: argument -q/--quiet: not allowed with argument -v/--verbose

這應該很容易理解。 我添加了末尾的輸出這樣你就可以看到其所達到的靈活性,即混合使用長和短兩種形式的選項。

在我們收尾之前,你也許希望告訴你的用戶這個程序的主要目標,以免他們還不清楚:

import argparse
parser = argparse.ArgumentParser(description="calculate X to the power of Y")
group = parser.add_mutually_exclusive_group()
group.add_argument("-v", "--verbose", action="store_true")
group.add_argument("-q", "--quiet", action="store_true")
parser.add_argument("x", type=int, help="the base")
parser.add_argument("y", type=int, help="the exponent")
args = parser.parse_args()
answer = args.x**args.y
if args.quiet:
print(answer)
elif args.verbose:
print("{} to the power {} equals {}".format(args.x, args.y, answer))
else:
print("{}^{} == {}".format(args.x, args.y, answer))

請注意用法文本中有細微的差異。 注意 [-v | -q],它的意思是說我們可以使用 -v-q,但不能同時使用兩者:

$ python3 prog.py --help
usage: prog.py [-h] [-v | -q] x y
calculate X to the power of Y
positional arguments:
x the base
y the exponent
options:
-h, --help show this help message and exit
-v, --verbose
-q, --quiet

二、Click 模塊

2.1 Click

Click 是 Flask 的開發團隊 Pallets 的另一款開源項目,它是用於快速創建命令行的第三方模塊。Click 是一個第三方庫,因此,在使用之前需要先安裝:

pip install click

Click 對 Argparse 的主要改進在易用性,使用Click 分為兩個步驟:

  1. 使用 @click.command() 裝飾一個函數,使之成為命令行接口;
  2. 使用 @click.option() 等裝飾函數,為其添加命令行選項等。

看一下官方文檔的入門例子:

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()

在上面的例子中,函數 hello 有兩個參數:count 和 name,它們的值從命令行中獲取。

  • @click.command() 使函數 hello 成為命令行接口;

  • @click.option 的第一個參數指定了命令行選項的名稱,可以看到,count 的默認值是 1;

  • 使用 click.echo 進行輸出是為了獲得更好的兼容性,因為 print 在 Python2 和 Python3 的用法有些差別。

執行情況:

$ python hello.py
Your name: Ethan # 這裡會顯示 'Your name: '(對應代碼中的 prompt),接受用戶輸入
Hello Ethan!
$ python hello.py --help # click 幫我們自動生成了 `--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 # 也可以使用 `=`,和上面等價
Hello Ethan!
Hello Ethan!
Hello Ethan!
$ python hello.py --name=Ethan # 沒有指定 count,默認值是 1
Hello Ethan!

2.2 group 使用

Click 通過 group 來創建一個命令行組,也就是說它可以有各種參數來解決相同類別的不同問題。

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()

2.3 click.option 使用

option 最基本的用法就是通過指定命令行選項的名稱,從命令行讀取參數值,再將其傳遞給函數。在上面的例子,我們看到,除了設置命令行選項的名稱,我們還會指定默認值,help 說明等,option 常用的設置參數如下:

  • default: 設置命令行參數的默認值。

  • help: 參數說明。

  • type: 參數類型,可以是 string, int, float 等。

  • prompt: 當在命令行中沒有輸入相應的參數時,會根據 prompt 提示用戶輸入。

  • nargs: 指定命令行參數接收的值的個數。

  • metavar:如何在幫助頁面表示值。

下面,我們再看看相關的例子。

2.3.1 type

我們可以使用 type 來指定參數類型:

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()

執行情況:

$ 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
2.3.2 可選值

在某些情況下,一個參數的值只能是某些可選的值,如果用戶輸入了其他值,我們應該提示用戶輸入正確的值。在這種情況下,我們可以通過 click.Choice() 來限定。
執行情況:

$ 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
2.3.3 多值參數

有時,一個參數需要接收多個值。option 支持設置固定長度的參數值,通過 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)
2.3.4 輸入密碼

有時,在輸入密碼的時候,我們希望能隱藏顯示。option 提供了兩個參數來設置密碼的輸入:hide_input 和 confirmation_promt,其中,hide_input 用於隱藏輸入,confirmation_promt 用於重復輸入。

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()

執行情況:

$ python click_password.py
Password: # 不會顯示密碼
Repeat for confirmation: # 重復一遍
password: 123

click 也提供了一種快捷的方式,通過使用 @click.password_option(),上面的代碼可以簡寫成:

import click
@click.command()
@click.password_option()
def input_password(password):
click.echo('password: %s' % password)
if __name__ == '__main__':
input_password()

2.4 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.

2.5 改變命令行程序的執行

有些參數會改變命令行程序的執行,比如在終端輸入 python 是進入 python 控制台,而輸入 python --version 是打印 python 版本。Click 提供 eager 標識對參數名進行標識,如果輸入該參數,則會攔截既定的命令行執行流程,跳轉去執行一個回調函數。

import click
def print_version(ctx, param, value):
if not value or ctx.resilient_parsing:
return
click.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 表明該命令行選項優先級高於其他選項;

  • expose_value=False 表示如果沒有輸入該命令行選項,會執行既定的命令行流程;

  • callback 指定了輸入該命令行選項時,要跳轉執行的函數

  • is_flag=True 表明參數值可以省略
    執行情況:

    $ python click_eager.py
    Hello Ethan!
    $ python click_eager.py --version # 攔截既定的命令行執行流程
    Version 1.0
    $ python click_eager.py --name Michael
    Hello Michael!
    $ python click_eager.py --version --name Ethan # 忽略 name 選項
    Version 1.0
    

後記

除了這裡顯示的內容,argparseClick 模塊還提供了更多功能。 它的文檔相當詳細和完整,包含大量示例。 完成這個教程之後,你應該能毫不困難地閱讀該文檔。


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved