Python學習教程:Pythonargparse模塊

這篇 Python學習教程主要是對 argparse(Python標準庫中推薦的命令行解析模塊) 進行簡要介紹。

成都創(chuàng)新互聯(lián)公司專業(yè)為企業(yè)提供綏化網(wǎng)站建設、綏化做網(wǎng)站、綏化網(wǎng)站設計、綏化網(wǎng)站制作等企業(yè)網(wǎng)站建設、網(wǎng)頁設計與制作、綏化企業(yè)網(wǎng)站模板建站服務,十載綏化做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡服務。

note 還有兩個其他模塊也可以完成相同的任務,分別是 getopt(與C語言中的 getopt() 等效)和已經(jīng)過時的 optparse。需要注意的是 argparse 也是基于 optparse,因此在用法上非常相似。

概念

讓我們通過使用 ls 命令來展示我們將在本 Python學習教程入門中探索的功能類型:

$ 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 命令在不接受任何參數(shù)時也是有作用的,它默認用于展示當前目錄下的內(nèi)容。
  • 如果我們想它讓提供非默認以外的功能,我們必須指定更多的參數(shù)。在這個例子中,我們想要展示一個不同的目錄:pypy。我們所做的是指定所謂的位置參數(shù)。之所以這樣命名,是因為程序僅根據(jù)命令行中的位置知道該值的用途。這個概念和 cp 之類的命令更相關,cp 命令最基本的用法是 cp SRC DEST。第一個位置是你要復制的內(nèi)容,第二個位置是你要復制到的位置。
  • 現(xiàn)在,假設我們要更改程序的行為。在我們的示例中,我們?yōu)槊總€文件顯示更多偏偏,而不僅僅是顯示文件名。在這種情況下,-l被稱為可選參數(shù)。
  • 這是幫助文本的的一小段。它非常有用,因為你可以通過它找到從未使用過的程序,并且只需要閱讀幫助文本即可了解其工作方式。
Python學習教程:Python argparse模塊

基礎用法

讓我們從一個非常簡單的例子開始,這個例子幾乎什么事情都沒做:

import argparse
parser = argparse.ArgumentParser()
parser.parse_args()

下面是執(zhí)行這段代碼的結(jié)果:

$ python3 prog.py
$ python3 prog.py --help
usage: prog.py [-h]
optional arguments:
 -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

下面是這段代碼做了什么的解釋:

  • 不帶任何參數(shù)執(zhí)行這個腳本沒有任何的輸出,沒有什么作用。
  • 第二個開始顯示 argparse 模塊的用處,我們幾乎什么也沒做,但是已經(jīng)得到了很好的幫助信息
  • --help 選項可以簡寫成 -h,它是唯一一個我們能指定的選項(即不需要代碼定義),指定任何其他的都會導致報錯。但即使這樣,我們?nèi)匀灰呀?jīng)免費獲得了幫助信息。

位置參數(shù)介紹

一個例子:

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

運行這段代碼:

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

代碼解釋:

  • 我們增加了 add_argument() 方法,這個方法用于指定程序可以接受的命令行。在這個例子中,我將它命名為 echo,與它的功能相符合。
  • 這時我們調(diào)用程序需要我們指定選項。
  • parse_args() 方法實際上會從我們指定的選項中返回一些數(shù)據(jù),在這個例子中為 echo。
  • 最近的 args.echo 是 argparse 內(nèi)部執(zhí)行的某種“魔法”(不需要手動指定哪個變量來存儲值)。同時它的名稱與執(zhí)行程序時傳入的字符串是一致的。

然而請注意,盡管幫助信息看起來不錯,但目前并不是很有用。例如,我們看到了我們將 echo 作為了位置參數(shù),但除了猜測和閱讀源代碼外,我們不知道它的作用。因此,讓我們將它變得更加有用:

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
optional arguments:
 -h, --help show this help message and exit

現(xiàn)在,讓我們來做一些更有用的事情:

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)

上面代碼執(zhí)行的結(jié)果如下:

$ 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'

結(jié)果不是很好,這是因為 argparse 將我們給的選項當成了字符串,除非我們手動指定類型。因此,讓我們來告訴 argparse 將它視為一個整數(shù):

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)

下面是上述代碼的執(zhí)行結(jié)果:

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

結(jié)果很好,程序甚至可以在執(zhí)行前因為錯誤輸入而結(jié)束。

可選參數(shù)介紹

到目前為止,我們已經(jīng)介紹過了位置參數(shù)。接下來讓我們看下如何添加一個可選參數(shù):

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

運行結(jié)果:

$ python3 prog.py --verbosity 1
verbosity turned on
$ python3 prog.py
$ python3 prog.py --help
usage: prog.py [-h] [--verbosity VERBOSITY]
optional arguments:
 -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 時輸出一些信息,而如果沒有指定則不展示任何信息。
  • 為了證明選項確實是可選的,當我們不帶選項運行程序時并沒有報錯。需要注意的是,如果一個可選參數(shù)沒有指定,與它相關聯(lián)的參數(shù)(在這個例子中是 args.verbosity),默認情況下會賦值為 None,這也是 if 語句為 False 的原因。
  • 幫助信息有一點不同。
  • 當我們使用 --verbosity 選項時,還必須指定一些值,任意值都可以。

上面的例子對于 --verbosity 還可以接受任意整數(shù),但對我們的程序來說,只有 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")

結(jié)果如下:

 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]
optional arguments:
 -h, --help show this help message and exit
 --verbose increase output verbosity

代碼解釋如下:

  • 現(xiàn)在這個選項更像是一個標記,而不是僅僅需要一個值。我們甚至修改了這個選項的名字來匹配這個想法。需要注意的是,我們指定了一個新的關鍵詞:action,并且它的值為:“store_true”。這意味著如果我們這個選項指定了,我們將給 args.verbose 賦值為 True,反之為 False。
  • 當你手動指定選項的值時會報錯,因為它實際存儲的是 True。
  • 注意幫助信息的不同。

短選項

如果你熟悉命令行的用法,你們發(fā)現(xiàn)目前為止我還沒有涉及這個選項的簡短版本的話題。下面是一個很簡單的示例:

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

執(zhí)行結(jié)果如下:

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

注意在幫助信息中反映了這個新的功能。

位置參數(shù)與可選參數(shù)的結(jié)合

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

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("the square of {} equals {}".format(args.square, 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
  • 我們重新加入了位置參數(shù),因此(直接運行程序)會報錯
  • 注意與選項順序無關

我們?nèi)绾巫屛覀冞@個程序具有多個 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,
 help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbosity == 2:
 print("the square of {} equals {}".format(args.square, answer))
elif args.verbosity == 1:
 print("{}^2 == {}".format(args.square, 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

上面結(jié)果除了最后一個看上去都沒問題。最后一個暴露了我們程序的一個 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("the square of {} equals {}".format(args.square, answer))
elif args.verbosity == 1:
 print("{}^2 == {}".format(args.square, 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
optional arguments:
 -h, --help show this help message and exit
 -v {0,1,2}, --verbosity {0,1,2}
 increase output verbosity

需要注意的是,對應的改變在報錯信息和幫助信息中都有體現(xiàn)。

現(xiàn)在,讓我們用另外一種更通用的方式來使用 verbosity 選項。這種方式與 CPython 解釋器中處理 verbosity 選項相同(可通過 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("the square of {} equals {}".format(args.square, answer))
elif args.verbosity == 1:
 print("{}^2 == {}".format(args.square, answer))
else:
 print(answer)

我們引入了另外一種 action:"count",它用于計算一個可選參數(shù)出現(xiàn)的次數(shù):

$ 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
optional arguments:
 -h, --help show this help message and exit
 -v, --verbosity increase output verbosity
$ python3 prog.py 4 -vvv
16

是的,現(xiàn)在我們的腳本比之前的版本多了一個標識(類似于之前的 action="store_true")。可以在報錯信息中看到這一解釋。

它和 "store_action" 的作用類似。

這里是對 "count" 作用的證明。你可以在之前已經(jīng)看到過這一個用法。

如果你不指定 -v 標識,這個標識被認為是 None。

正如我們認為的一樣,當我們使用長選項,輸出結(jié)果仍然是一樣的。

然而,我們的幫助信息對這一個新功能解釋得不是很好,但這一點仍舊是可以通過修改腳本代碼來修復的(通過 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("the square of {} equals {}".format(args.square, answer))
elif args.verbosity >= 1:
 print("{}^2 == {}".format(args.square, 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'

開始的輸出結(jié)果很理想,并且修復了之前的bug。也就是說,我們希望任何 >=2的值都盡可能詳細。

第三個輸出結(jié)果不是很理想

讓我們修復這個 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("the square of {} equals {}".format(args.square, answer))
elif args.verbosity >= 1:
 print("{}^2 == {}".format(args.square, answer))
else:
 print(answer)

我們剛剛引入了另外一個關鍵詞:default。我們把它設置為 0 是為了讓它可以進行整數(shù)比較。記住,默認情況下,如果一個可選參數(shù)沒有被指定,它將得到 None 值,它不能進行整數(shù)比較(因此會報 TypeError 異常)。

這時我們再執(zhí)行:

$ python3 prog.py 4
16

就目前為止所學到的東西,您可以走的很遠,而且我們只是從頭開始。 argparse模塊功能非常強大,在結(jié)束本教程之前,我們將對其進行更多的探索。

深入一點

如果我們想擴展我們的小程序以執(zhí)行其他冪運算,而不僅僅是做平方:

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("{} to the power {} equals {}".format(args.x, args.y, answer))
elif args.verbosity >= 1:
 print("{}^{} == {}".format(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
optional arguments:
 -h, --help show this help message and exit
 -v, --verbosity
$ python3 prog.py 4 2 -v
4^2 == 16

請注意,到目前為止,我們一直在使用 verbosity 級別來更改顯示的文本。下面的示例改為使用 verbosity 級別來顯示更多文本:

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("Running '{}'".format(__file__))
if args.verbosity >= 1:
 print("{}^{} == ".format(args.x, args.y), end="")
print(answer)

結(jié)果:

$ 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

沖突的選項

目前為止,我們一直使用 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("{} to the power {} equals {}".format(args.x, args.y, answer))
else:
 print("{}^{} == {}".format(args.x, args.y, answer))

我們的程序更加簡單了,為了演示我們丟掉了一些功能??傊?,下面是輸出結(jié)果:

$ 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

那應該很容易理解。在最后一個輸出里,我添加了長選項與短選項的混合,這樣你能看到選項順序的靈活性。

在我們總結(jié)之前,你可能會想告訴用戶你程序主要用來做什么,以防他們不知道:

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] 是告訴我們可以使用任意一個,但不能同時使用:

$ 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
optional arguments:
 -h, --help show this help message and exit
 -v, --verbose
 -q, --quiet

總結(jié)

argparse模塊提供的功能遠遠超出此處所示。它的文檔非常詳細和透徹,并有許多示例。相信你在閱讀完本次的 Python學習教程后,應該輕松消化它們,而不會感到不知所措。更多的 Python學習教程也會繼續(xù)為大家更新,伙伴們有不清楚的地方,可以留言!

分享名稱:Python學習教程:Pythonargparse模塊
本文URL:http://muchs.cn/article6/gpjsog.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設計、動態(tài)網(wǎng)站、企業(yè)網(wǎng)站制作自適應網(wǎng)站、網(wǎng)站排名、域名注冊

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

h5響應式網(wǎng)站建設