(轉) argparse — 解析命令參數和選項


原文地址:https://pythoncaff.com/docs/pymotw/argparse-command-line-option-and-argument-parsing/166

https://docs.python.org/3/library/argparse.html?highlight=argparse#module-argparse-------argparse 官網

http://www.cnblogs.com/arkenstone/p/6250782.html------Python3 -- argparse模塊

http://blog.csdn.net/WIinter_FDd/article/details/75786410

 https://oldpan.me/archives/argparse-python-order-command--------Argparse-parser模塊:python快捷實現命令行操作

這是一篇社區協同翻譯的文章,你可以點擊右邊區塊信息里的『改進』按鈕向譯者提交改進建議。

目標:命令行選項和參數解析

argparse 模塊包含了用於創建命令行參數和選項程序的工具。它在 Python 2.7 中加入並作為 optparse 模塊的替代者。argparse 模塊的實現支持那些在 optparse 中不容易實現的特征,這也導致了向后不兼容的 API 改變,所以是一個新的模塊被加入到標准庫中。optparse 現在已經被廢棄。

創建一個解析器##

使用 argparse 的第一步是創建一個解析器對象然后告訴它要接收什么參數。解析器隨后可以在程序運行時用於處理命令行參數。解析器對象 (ArgumentParser) 的構造器接收一些參數來構建用於幫助文本的簡介和其他全局表現設置。

import argparse parser = argparse.ArgumentParser( description='This is a PyMOTW sample program', ) 
Rookie 翻譯於 5個月前
 
由  Summer 審閱
 

定義參數##

arpparse 是一個完整的參數處理庫。參數可以觸發不同動作,這可以通過 add_argument() 的 action 參數來聲明。支持的動作包括儲存參數值(單獨地或這作為列表的一部分存儲),當使用一個參數時(包括特殊 true/false 的布爾型數值轉換處理)存儲一個常數,對參數出現次數進行計數和使用回調函數來使用定制的處理指令。

默認的動作是存儲參數值。如果指定了參數類型,參數值會在被儲存前轉換。如果提供了 dest 參數,命令行參數被解析時參數值會以 dest 參數提供的變量名存儲。

解析一個命令行##

在所有參數都被定義后,通過傳遞一組參數字符串序列給 parse_args() 來解析參數。默認情況下,所有參數從 sys.argv[1:] 中取得,但也可以使用一個字符串列表。選項使用 GNU/POSIX 語法處理,所以選項和參數值在序列里是混合的。

parse_args() 的返回值是一個包含命令參數的 Namespace。這個對象將參數值作為屬性保存,所以如果參數的 dest 被設為 "myoption",參數值可以通過 args.myoption 的方式獲取。

Rookie 翻譯於 5個月前
 
由  Summer 審閱
 

簡單的例子##

以下是一個有三個不同選項的例子:一個布爾型選項 (-a), 一個簡單的字符串選項 (-b), 和一個整數選項 (-c) 。

argparse_short.py

import argparse parser = argparse.ArgumentParser(description='Short sample app') parser.add_argument('-a', action="store_true", default=False) parser.add_argument('-b', action="store", dest="b") parser.add_argument('-c', action="store", dest="c", type=int) print(parser.parse_args(['-a', '-bval', '-c', '3'])) 

單字符選項傳值有幾種方式。前面的例子展示了兩種不同的方式,-bval 和 -c val

$ python3 argparse_short.py Namespace(a=True, b='val', c=3) 

與 c 相關的值在輸出中是一個整數,這是因為 ArgumentParser 被告知在保存這個參數之前要進行轉換。

名稱多於一個字符的選項,也就是“長”選項也是以這樣的方式處理的。

argparse_long.py

import argparse parser = argparse.ArgumentParser( description='Example with long option names', ) parser.add_argument('--noarg', action="store_true", default=False) parser.add_argument('--witharg', action="store", dest="witharg") parser.add_argument('--witharg2', action="store", dest="witharg2", type=int) print( parser.parse_args( ['--noarg', '--witharg', 'val', '--witharg2=3'] ) ) 

結果是類似的。

$ python3 argparse_long.py Namespace(noarg=True, witharg='val', witharg2=3) 

argparse 是一個完整的命令行參數解析工具,可以處理可選參數和必須參數。

argparse_arguments.py

import argparse parser = argparse.ArgumentParser( description='Example with nonoptional arguments', ) parser.add_argument('count', action="store", type=int) parser.add_argument('units', action="store") print(parser.parse_args()) 

在這個例子中,count 參數值是一個整數,unit 參數值以一個字符串保存。如果命令行中缺少了兩個參數中任何一個,或者傳遞的值不能被轉換為正確的類型,將會拋出錯誤。

$ python3 argparse_arguments.py 3 inches Namespace(count=3, units='inches') $ python3 argparse_arguments.py some inches usage: argparse_arguments.py [-h] count units argparse_arguments.py: error: argument count: invalid int value: 'some' $ python3 argparse_arguments.py usage: argparse_arguments.py [-h] count units argparse_arguments.py: error: the following arguments are required: count, units 
Rookie 翻譯於 5個月前
 
由  Summer 審閱
 

參數動作##

當一個參數被傳遞時可以觸發任何6個內建動作的任何一個。

store

選擇性地轉換為一個不同的類型后保存參數值。如果沒有特別聲明動作時這是默認動作。

store_const

保存一個在參數聲明時定義的值,而非解析參數時得到的值。這通常被用於實現非布爾型數值的命令行標志。

store_true / store_false

保存相應的布爾型數值,這個動作被用於實現布爾值開關。

append

將參數值保存在一個列表中。如果參數重復了,那么多個參數值將會被保存。

append_const

將參數值保存在參數聲明時指定的列表中。

version

打印程序版本詳情然后退出

這個示例程序演示了讓每個動作類型能夠工作的最少配置。

argparse_action.py

import argparse parser = argparse.ArgumentParser() parser.add_argument('-s', action='store', dest='simple_value', help='Store a simple value') parser.add_argument('-c', action='store_const', dest='constant_value', const='value-to-store', help='Store a constant value') parser.add_argument('-t', action='store_true', default=False, dest='boolean_t', help='Set a switch to true') parser.add_argument('-f', action='store_false', default=True, dest='boolean_f', help='Set a switch to false') parser.add_argument('-a', action='append', dest='collection', default=[], help='Add repeated values to a list') parser.add_argument('-A', action='append_const', dest='const_collection', const='value-1-to-append', default=[], help='Add different values to list') parser.add_argument('-B', action='append_const', dest='const_collection', const='value-2-to-append', help='Add different values to list') parser.add_argument('--version', action='version', version='%(prog)s 1.0') results = parser.parse_args() print('simple_value = {!r}'.format(results.simple_value)) print('constant_value = {!r}'.format(results.constant_value)) print('boolean_t = {!r}'.format(results.boolean_t)) print('boolean_f = {!r}'.format(results.boolean_f)) print('collection = {!r}'.format(results.collection)) print('const_collection = {!r}'.format(results.const_collection)) 

 -t 和 -f 選項用於設置修改不同選項值,每個保存 True 或 False。-A 和 -B 的 dest 參數值相同,所以它們的常量會被添加到相同的列表中。

$ python3 argparse_action.py -h usage: argparse_action.py [-h] [-s SIMPLE_VALUE] [-c] [-t] [-f] [-a COLLECTION] [-A] [-B] [--version] optional arguments: -h, --help show this help message and exit -s SIMPLE_VALUE Store a simple value -c Store a constant value -t Set a switch to true -f Set a switch to false -a COLLECTION Add repeated values to a list -A Add different values to list -B Add different values to list --version show program's version number and exit $ python3 argparse_action.py -s value simple_value = 'value' constant_value = None boolean_t = False boolean_f = True collection = [] const_collection = [] $ python3 argparse_action.py -c simple_value = None constant_value = 'value-to-store' boolean_t = False boolean_f = True collection = [] const_collection = [] $ python3 argparse_action.py -t simple_value = None constant_value = None boolean_t = True boolean_f = True collection = [] const_collection = [] $ python3 argparse_action.py -f simple_value = None constant_value = None boolean_t = False boolean_f = False collection = [] const_collection = [] $ python3 argparse_action.py -a one -a two -a three simple_value = None constant_value = None boolean_t = False boolean_f = True collection = ['one', 'two', 'three'] const_collection = [] $ python3 argparse_action.py -B -A simple_value = None constant_value = None boolean_t = False boolean_f = True collection = [] const_collection = ['value-2-to-append', 'value-1-to-append'] $ python3 argparse_action.py --version argparse_action.py 1.0 
Rookie 翻譯於 5個月前
 
由  Summer 審閱
 

選項前綴##

默認語法是基於使用前綴(“-”)表示命令行開關的Unix慣例。argparse 支持也其他前綴,所以程序可以使用符合本地操作系統默認的前綴(比如 windows 的 “'/'”)或者遵循不同的慣例。

argparse_prefix_chars.py

import argparse parser = argparse.ArgumentParser( description='Change the option prefix characters', prefix_chars='-+/', ) parser.add_argument('-a', action="store_false", default=None, help='Turn A off', ) parser.add_argument('+a', action="store_true", default=None, help='Turn A on', ) parser.add_argument('//noarg', '++noarg', action="store_true", default=False) print(parser.parse_args()) 

你可以把 ArgumentParser 的 prefix_chars 參數設置為一個包含所有允許的前綴的字符串。重要的一點是要理解盡管 prefix_chars 明確了允許的開關字符,但參數定義時指明了該參數的可用前綴。這樣可以精確地控制選項功能,使用不同前綴可能僅僅是選項的別名(比如說平台依賴的命令行語法)或者其他意義(比如使用 '+' 來表示打開某個選項,'-' 來表示關閉某選項)。在上面的例子中,+a 和 -a 是不同的參數,而 //noarg 可以使用 ++noarg 樣式,但不能是 --noarg

$ python3 argparse_prefix_chars.py -h usage: argparse_prefix_chars.py [-h] [-a] [+a] [//noarg] Change the option prefix characters optional arguments: -h, --help show this help message and exit -a Turn A off +a Turn A on //noarg, ++noarg $ python3 argparse_prefix_chars.py +a Namespace(a=True, noarg=False) $ python3 argparse_prefix_chars.py -a Namespace(a=False, noarg=False) $ python3 argparse_prefix_chars.py //noarg Namespace(a=None, noarg=True) $ python3 argparse_prefix_chars.py ++noarg Namespace(a=None, noarg=True) $ python3 argparse_prefix_chars.py --noarg usage: argparse_prefix_chars.py [-h] [-a] [+a] [//noarg] argparse_prefix_chars.py: error: unrecognized arguments: --noarg 
Rookie 翻譯於 5個月前
 
由  Summer 審閱
 

參數來源##

目前的例子里,解析器接收的參數列表來自於顯式傳遞的一個列表,或默認從 sys.argv 中獲取。顯示傳遞一個列表給解析器在使用 argparse 來處理不來自命令行的但像命令行一樣的指令(比如該命令來自配置文件)很有用。

argparse_with_shlex.py

import argparse from configparser import ConfigParser import shlex parser = argparse.ArgumentParser(description='Short sample app') parser.add_argument('-a', action="store_true", default=False) parser.add_argument('-b', action="store", dest="b") parser.add_argument('-c', action="store", dest="c", type=int) config = ConfigParser() config.read('argparse_with_shlex.ini') config_value = config.get('cli', 'options') print('Config :', config_value) argument_list = shlex.split(config_value) print('Arg List:', argument_list) print('Results :', parser.parse_args(argument_list)) 

這個例子使用 configparser 讀取配置文件。

[cli] options = -a -b 2 

shlex 可以讓拆開配置文件中的字符串變得容易。

$ python3 argparse_with_shlex.py Config : -a -b 2 Arg List: ['-a', '-b', '2'] Results : Namespace(a=True, b='2', c=None) 

在應用程序代碼中處理配置文件的另一個方案是使用 fromfile_prefix_chars 告訴 argparse 識別一個特殊參數,這個參數指明了包涵需要處理的參數的文件。

argparse_fromfile_prefix_chars.py

import argparse import shlex parser = argparse.ArgumentParser(description='Short sample app', fromfile_prefix_chars='@', ) parser.add_argument('-a', action="store_true", default=False) parser.add_argument('-b', action="store", dest="b") parser.add_argument('-c', action="store", dest="c", type=int) print(parser.parse_args(['@argparse_fromfile_prefix_chars.txt'])) 

這個例子的代碼會在發現一個 @ 前綴的參數時停下,然后讀取該文件來找到更多參數。這個文件應該每行包含一個參數,如下面例子所示。

argparse_fromfile_prefix_chars.txt

-a -b 2 

解析 argparse_from_prefix_chars.txt 的輸出如下。

$ python3 argparse_fromfile_prefix_chars.py Namespace(a=True, b='2', c=None) 
Rookie 翻譯於 5個月前
 
由  Summer 審閱
 

幫助內容##

自動生成的幫助文本##

如果配置為這樣做,argparse 會自動生成選項的幫助文本。ArgumentParser 的 add_help 參數可以控制相關選項。

argparse_with_help.py

import argparse parser = argparse.ArgumentParser(add_help=True) parser.add_argument('-a', action="store_true", default=False) parser.add_argument('-b', action="store", dest="b") parser.add_argument('-c', action="store", dest="c", type=int) print(parser.parse_args()) 

幫助選項(-h 和 --help )默認會被自動添加,可以設置 add_help 為 False 來停用這個功能。

argparse_without_help.py

import argparse parser = argparse.ArgumentParser(add_help=False) parser.add_argument('-a', action="store_true", default=False) parser.add_argument('-b', action="store", dest="b") parser.add_argument('-c', action="store", dest="c", type=int) print(parser.parse_args()) 

盡管 -h 和 --help 是請求幫助選項的事實標准,一些應用或某些 argparse 的用法不需要提供幫助內容或這兩個選項另有他用。

$ python3 argparse_with_help.py -h usage: argparse_with_help.py [-h] [-a] [-b B] [-c C] optional arguments: -h, --help show this help message and exit -a -b B -c C $ python3 argparse_without_help.py -h usage: argparse_without_help.py [-a] [-b B] [-c C] argparse_without_help.py: error: unrecognized arguments: -h 
Rookie 翻譯於 5個月前
 
由  Summer 審閱
 

定制幫助內容##

對於需要直接處理幫助內容的應用,ArgumentParser 的一些實用方法在創建 定制動作 來打印帶有額外信息的幫助文本時很有用。

argparse_custom_help.py

import argparse parser = argparse.ArgumentParser(add_help=True) parser.add_argument('-a', action="store_true", default=False) parser.add_argument('-b', action="store", dest="b") parser.add_argument('-c', action="store", dest="c", type=int) print('print_usage output:') parser.print_usage() print() print('print_help output:') parser.print_help() 

print_usage() 打印參數解析器的簡略使用信息,print_help() 會打印完整幫助文本。

$ python3 argparse_custom_help.py print_usage output: usage: argparse_custom_help.py [-h] [-a] [-b B] [-c C] print_help output: usage: argparse_custom_help.py [-h] [-a] [-b B] [-c C] optional arguments: -h, --help show this help message and exit -a -b B -c C 

ArgumentParser 使用一個格式化類來控制幫助文本的顯示樣式。要改變格式化類,可以在實例化 ArgumentParser 時傳遞 formatter_class 參數。

例如,RawDescriptionHelpFormatter 會繞過程序默認提供的換行。

argparse_raw_description_help_formatter.py

import argparse parser = argparse.ArgumentParser( add_help=True, formatter_class=argparse.RawDescriptionHelpFormatter, description=""" description not wrapped""", epilog=""" epilog not wrapped""", ) parser.add_argument( '-a', action="store_true", help="""argument help is wrapped """, ) parser.print_help() 

命令的介紹和結語的幫助文本會原封不動地打印。

$ python3 argparse_raw_description_help_formatter.py usage: argparse_raw_description_help_formatter.py [-h] [-a] description not wrapped optional arguments: -h, --help show this help message and exit -a argument help is wrapped epilog not wrapped 

 RawTextHelpFormatter 視所有幫助文本都是預格式化好的。

argparse_raw_text_help_formatter.py

import argparse parser = argparse.ArgumentParser( add_help=True, formatter_class=argparse.RawTextHelpFormatter, description=""" description not wrapped""", epilog=""" epilog not wrapped""", ) parser.add_argument( '-a', action="store_true", help="""argument help is not wrapped """, ) parser.print_help() 

-a 的幫助文本不會再別整齊地包裝起來。

$ python3 argparse_raw_text_help_formatter.py usage: argparse_raw_text_help_formatter.py [-h] [-a] description not wrapped optional arguments: -h, --help show this help message and exit -a argument help is not wrapped epilog not wrapped 

原始格式化類可能用於改變幫助文本的格式可能會讓例子失效的應用程序中。

 MetavarTypeHelpFormatter 還會打印每個選項的類型而非僅有目標變量名稱,這個格式化類可用於有很多不同類型選項的應用程序。

argparse_metavar_type_help_formatter.py

import argparse parser = argparse.ArgumentParser( add_help=True, formatter_class=argparse.MetavarTypeHelpFormatter, ) parser.add_argument('-i', type=int, dest='notshown1') parser.add_argument('-f', type=float, dest='notshown2') parser.print_help() 

除了顯示 dest 的值,與選項相關的參數值類型也會被打印。

$ python3 argparse_metavar_type_help_formatter.py usage: argparse_metavar_type_help_formatter.py [-h] [-i int] [-f float] optional arguments: -h, --help show this help message and exit -i int -f float 
Rookie 翻譯於 5個月前
 
由  Summer 審閱
 

組織解析器##

為了讓實現解析器或提高幫助文本的可用性, argparse 模塊提供幾個功能來組織參數解析器。

分享解析規則##

程序員通常需要實現一套命令行工具,這個工具接收一組參數,並以某特定方式使用這組參數。例如,一些程序需要在真正執行動作前對用戶進行認證,它們都需要支持 --user 和 --password 選項。除了單獨地向每個 ArgumentParser 都添加這兩個選項外,先定義一個帶有共享參數的父解析器,接着繼承父解析器並編寫用於某特定程序的參數解析器也是一種可能的方案。

第一步是建立有共享參數解析器。由於后續使用父解析器的用戶會嘗試添加相同的幫助選項,這將會拋出錯誤,所以父解析器自動生成幫助文本特性被關閉了。

argparse_parent_base.py

import argparse parser = argparse.ArgumentParser(add_help=False) parser.add_argument('--user', action="store") parser.add_argument('--password', action="store") 

接下來創建一個使用共享 parents 參數集的解析器:

argparse_uses_parent.py

import argparse import argparse_parent_base parser = argparse.ArgumentParser( parents=[argparse_parent_base.parser], ) parser.add_argument('--local-arg', action="store_true", default=False) print(parser.parse_args()) 

最后程序會有所有的三個選項。

$ python3 argparse_uses_parent.py -h usage: argparse_uses_parent.py [-h] [--user USER] [--password PASSWORD] [--local-arg] optional arguments: -h, --help show this help message and exit --user USER --password PASSWORD --local-arg 

沖突選項##

上面的例子指出添加兩個參數名相同的選項會導致異常。沖突解決行為可以通過傳遞一個 confilct_handler 來改變。兩個內建的處理器是 error (默認)和 resolve ,這處理器會根據同名參數的添加順序選擇參數處理器,即后續同名參數會覆蓋之前的同名參數。

argparse_conflict_handler_resolve.py

import argparse parser = argparse.ArgumentParser(conflict_handler='resolve') parser.add_argument('-a', action="store") parser.add_argument('-b', action="store", help='Short alone') parser.add_argument('--long-b', '-b', action="store", help='Long and short together') print(parser.parse_args(['-h'])) 

在這個例子中,由於最后一個參數處理器使用了已經定義過的參數名,單獨選項 -b 會被 --long-b 的別名掩蓋。

$ python3 argparse_conflict_handler_resolve.py usage: argparse_conflict_handler_resolve.py [-h] [-a A] [--long-b LONG_B] optional arguments: -h, --help show this help message and exit -a A --long-b LONG_B, -b LONG_B Long and short together 

交換 add_argument() 的調用順序可以獨立的 -b 不被掩蓋:

argparse_conflict_handler_resolve2.py

import argparse parser = argparse.ArgumentParser(conflict_handler='resolve') parser.add_argument('-a', action="store") parser.add_argument('--long-b', '-b', action="store", help='Long and short together') parser.add_argument('-b', action="store", help='Short alone') print(parser.parse_args(['-h'])) 

現在兩個選項可以一起使用了。

$ python3 argparse_conflict_handler_resolve2.py usage: argparse_conflict_handler_resolve2.py [-h] [-a A] [--long-b LONG_B] [-b B] optional arguments: -h, --help show this help message and exit -a A --long-b LONG_B Long and short together -b B Short alone 
Rookie 翻譯於 5個月前
 
由  Summer 審閱
 

參數組##

argparse 把參數定義組合為 “參數組” 。默認情況下,它使用兩個參數組,一個用於可選參數,一個用於位置參數。

argparse_default_grouping.py

import argparse parser = argparse.ArgumentParser(description='Short sample app') parser.add_argument('--optional', action="store_true", default=False) parser.add_argument('positional', action="store") print(parser.parse_args()) 

位置參數和可選參數的分組反映在幫助文本的不同區塊。

$ python3 argparse_default_grouping.py -h usage: argparse_default_grouping.py [-h] [--optional] positional Short sample app positional arguments: positional optional arguments: -h, --help show this help message and exit --optional 

分組可以改變以讓幫助文本更有邏輯性,這樣可以讓相關的選項和參數值會被一起歸檔。之前的共享選項例子可以使用定制分組以讓認證選項一起出現在幫助文本中。

使用 add_argument_group 創建 “authentication” 分組,然后向分組添加認證相關選項到這個分組中,而非基礎解析器。

argparse_parent_with_group.py

import argparse parser = argparse.ArgumentParser(add_help=False) group = parser.add_argument_group('authentication') group.add_argument('--user', action="store") group.add_argument('--password', action="store") 

正如之前的用法,程序可以使用基於分組的父解析器作為 parents 的值。

argparse_uses_parent_with_group.py

import argparse import argparse_parent_with_group parser = argparse.ArgumentParser( parents=[argparse_parent_with_group.parser], ) parser.add_argument('--local-arg', action="store_true", default=False) print(parser.parse_args()) 

現在幫助文本會把認證選項顯示在一起。

$ python3 argparse_uses_parent_with_group.py -h usage: argparse_uses_parent_with_group.py [-h] [--user USER] [--password PASSWORD] [--local-arg] optional arguments: -h, --help show this help message and exit --local-arg authentication: --user USER --password PASSWORD 
Rookie 翻譯於 5個月前
 
由  Summer 審閱
 

互斥選項##

定義互斥選項是使用分組特性的特殊情況,這時需要使用 add_mutually_exclusive_group() 而不是 add_argument_group()

argparse_mutually_exclusive.py

import argparse parser = argparse.ArgumentParser() group = parser.add_mutually_exclusive_group() group.add_argument('-a', action='store_true') group.add_argument('-b', action='store_true') print(parser.parse_args()) 

argparse 會保證互斥性,這會讓組內只有一個選項可以使用。

$ python3 argparse_mutually_exclusive.py -h usage: argparse_mutually_exclusive.py [-h] [-a | -b] optional arguments: -h, --help show this help message and exit -a -b $ python3 argparse_mutually_exclusive.py -a Namespace(a=True, b=False) $ python3 argparse_mutually_exclusive.py -b Namespace(a=False, b=True) $ python3 argparse_mutually_exclusive.py -a -b usage: argparse_mutually_exclusive.py [-h] [-a | -b] argparse_mutually_exclusive.py: error: argument -b: not allowed with argument -a 
Rookie 翻譯於 5個月前
 
由  Summer 審閱
 

嵌套解析器##

之前介紹的使用父解析器是在相關命令之間共享選項的一種方法。一個替代方案是將這些命令組合到單個程序中,使用子解析器來處理命令行的每個部分。這樣程序就如 svnhg 和其他有多個命令動作作或子命令的程序一樣工作。

一個處理系統目錄的程序可能會定義創建,刪除和列舉目錄內容的命令。

argparse_subparsers.py

import argparse parser = argparse.ArgumentParser() subparsers = parser.add_subparsers(help='commands') # 一個列舉命令 list_parser = subparsers.add_parser( 'list', help='List contents') list_parser.add_argument( 'dirname', action='store', help='Directory to list') # 一個創建命令 create_parser = subparsers.add_parser( 'create', help='Create a directory') create_parser.add_argument( 'dirname', action='store', help='New directory to create') create_parser.add_argument( '--read-only', default=False, action='store_true', help='Set permissions to prevent writing to the directory', ) # 一個刪除命令 delete_parser = subparsers.add_parser( 'delete', help='Remove a directory') delete_parser.add_argument( 'dirname', action='store', help='The directory to remove') delete_parser.add_argument( '--recursive', '-r', default=False, action='store_true', help='Remove the contents of the directory, too', ) print(parser.parse_args()) 

幫助輸出將命名的子解析器顯示為“命令”,這個“命令”可以在命令行中將其指定為位置參數。

$ python3 argparse_subparsers.py -h usage: argparse_subparsers.py [-h] {list,create,delete} ... positional arguments: {list,create,delete} commands list List contents create Create a directory delete Remove a directory optional arguments: -h, --help show this help message and exit 

每個子解析器也可用擁有它自己的幫助文本,用於介紹該命令的參數選項。

$ python3 argparse_subparsers.py create -h usage: argparse_subparsers.py create [-h] [--read-only] dirname positional arguments: dirname New directory to create optional arguments: -h, --help show this help message and exit --read-only Set permissions to prevent writing to the directo ry 

當解析參數時,parse_args() 返回的 Namespace 對象只包含命令相關的值。

$ python3 argparse_subparsers.py delete -r foo Namespace(dirname='foo', recursive=True) 
Rookie 翻譯於 5個月前
 
由  Summer 審閱
 

高級參數處理##

目前的例子展示了簡單的布爾標志,字符串選項或數值參數,還有位置參數。argparse 也支持用於變長參數列表,枚舉和常量的復雜參數定義。

變長參數列表##

單個參數定義可以被配置於用來接收來自命令行的多個參數。根據需要或期望的參數個數把 nargs 設為下面表格中的一個。

argparse 變長參數定義標志

含義
N 參數確切個數(比如 3 個)
? 0 或 1 個參數
* 0 或更多參數
+ 至少有一個參數

argparse_nargs.py

import argparse parser = argparse.ArgumentParser() parser.add_argument('--three', nargs=3) parser.add_argument('--optional', nargs='?') parser.add_argument('--all', nargs='*', dest='all') parser.add_argument('--one-or-more', nargs='+') print(parser.parse_args()) 

解析器強制執行參數計數指令,並生成確切的語法圖作為命令幫助文本的一部分。

$ python3 argparse_nargs.py -h usage: argparse_nargs.py [-h] [--three THREE THREE THREE] [--optional [OPTIONAL]] [--all [ALL [ALL ...]]] [--one-or-more ONE_OR_MORE [ONE_OR_MORE ...]] optional arguments: -h, --help show this help message and exit --three THREE THREE THREE --optional [OPTIONAL] --all [ALL [ALL ...]] --one-or-more ONE_OR_MORE [ONE_OR_MORE ...] $ python3 argparse_nargs.py Namespace(all=None, one_or_more=None, optional=None, three=None) $ python3 argparse_nargs.py --three usage: argparse_nargs.py [-h] [--three THREE THREE THREE] [--optional [OPTIONAL]] [--all [ALL [ALL ...]]] [--one-or-more ONE_OR_MORE [ONE_OR_MORE ...]] argparse_nargs.py: error: argument --three: expected 3 argument(s) $ python3 argparse_nargs.py --three a b c Namespace(all=None, one_or_more=None, optional=None, three=['a', 'b', 'c']) $ python3 argparse_nargs.py --optional Namespace(all=None, one_or_more=None, optional=None, three=None) $ python3 argparse_nargs.py --optional with_value Namespace(all=None, one_or_more=None, optional='with_value', three=None) $ python3 argparse_nargs.py --all with multiple values Namespace(all=['with', 'multiple', 'values'], one_or_more=None, optional=None, three=None) $ python3 argparse_nargs.py --one-or-more with_value Namespace(all=None, one_or_more=['with_value'], optional=None, three=None) $ python3 argparse_nargs.py --one-or-more with multiple values Namespace(all=None, one_or_more=['with', 'multiple', 'values'], optional=None, three=None) $ python3 argparse_nargs.py --one-or-more usage: argparse_nargs.py [-h] [--three THREE THREE THREE] [--optional [OPTIONAL]] [--all [ALL [ALL ...]]] [--one-or-more ONE_OR_MORE [ONE_OR_MORE ...]] argparse_nargs.py: error: argument --one-or-more: expected at least one argument 
Rookie 翻譯於 5個月前
 
由  Summer 審閱
 

參數類型##

argparse 將所有參數視為字符串,除非被告知要將參數轉換為其他類型。add_argument() 的 type() 參數定義了一個轉換函數,這個函數會被 ArgumentParser 用來把參數值轉換為其他類型。

argparse_type.py

import argparse parser = argparse.ArgumentParser() parser.add_argument('-i', type=int) parser.add_argument('-f', type=float) parser.add_argument('--file', type=open) try: print(parser.parse_args()) except IOError as msg: parser.error(str(msg)) 

任何接收一個字符串的可調用對象都可以被傳遞為 type,包括內建類型比如 int 和 float 甚至 open()

$ python3 argparse_type.py -i 1 Namespace(f=None, file=None, i=1) $ python3 argparse_type.py -f 3.14 Namespace(f=3.14, file=None, i=None) $ python3 argparse_type.py --file argparse_type.py Namespace(f=None, file=<_io.TextIOWrapper name='argparse_type.py' mode='r' encoding='UTF-8'>, i=None) 

如果類型轉換失敗,argparser 會拋出一個異常。TypeError 和 ValueError 會被自動捕捉並轉換為簡單的錯誤信息提供給用戶。其他錯誤,比如下面例子里輸入文件不存在導致的 IOError 必須由調用者處理。

$ python3 argparse_type.py -i a usage: argparse_type.py [-h] [-i I] [-f F] [--file FILE] argparse_type.py: error: argument -i: invalid int value: 'a' $ python3 argparse_type.py -f 3.14.15 usage: argparse_type.py [-h] [-i I] [-f F] [--file FILE] argparse_type.py: error: argument -f: invalid float value: '3.14.15' $ python3 argparse_type.py --file does_not_exist.txt usage: argparse_type.py [-h] [-i I] [-f F] [--file FILE] argparse_type.py: error: [Errno 2] No such file or directory: 'does_not_exist.txt' 

要限制參數值為預先定義的一組值,可以使用 choices 參數。

argparse_choices.py

import argparse parser = argparse.ArgumentParser() parser.add_argument( '--mode', choices=('read-only', 'read-write'), ) print(parser.parse_args()) 

如果 --mode 的參數值不是允許值之一,程序會拋出錯誤並停止。

$ python3 argparse_choices.py -h usage: argparse_choices.py [-h] [--mode {read-only,read-write}] optional arguments: -h, --help show this help message and exit --mode {read-only,read-write} $ python3 argparse_choices.py --mode read-only Namespace(mode='read-only') $ python3 argparse_choices.py --mode invalid usage: argparse_choices.py [-h] [--mode {read-only,read-write}] argparse_choices.py: error: argument --mode: invalid choice: 'invalid' (choose from 'read-only', 'read-write') 
Rookie 翻譯於 5個月前
 
由  Summer 審閱
 

文件參數##

盡管 file 對象可以通過一個字符串參數實例化,但這個對象沒有包含訪問模式參數。FileType 提供了一種更靈活的方式來指定一個參數是文件,並且包含了訪問模式和緩沖區大小。

argparse_FileType.py

import argparse parser = argparse.ArgumentParser() parser.add_argument('-i', metavar='in-file', type=argparse.FileType('rt')) parser.add_argument('-o', metavar='out-file', type=argparse.FileType('wt')) try: results = parser.parse_args() print('Input file:', results.i) print('Output file:', results.o) except IOError as msg: parser.error(str(msg)) 

解析后的參數值是被打開文件的句柄。應用程序要負責不需要文件后關閉文件。

$ python3 argparse_FileType.py -h usage: argparse_FileType.py [-h] [-i in-file] [-o out-file] optional arguments: -h, --help show this help message and exit -i in-file -o out-file $ python3 argparse_FileType.py -i argparse_FileType.py -o tmp_\ file.txt Input file: <_io.TextIOWrapper name='argparse_FileType.py' mode='rt' encoding='UTF-8'> Output file: <_io.TextIOWrapper name='tmp_file.txt' mode='wt' encoding='UTF-8'> $ python3 argparse_FileType.py -i no_such_file.txt usage: argparse_FileType.py [-h] [-i in-file] [-o out-file] argparse_FileType.py: error: argument -i: can't open 'no_such_file.txt': [Errno 2] No such file or directory: 'no_such_file.txt' 
Rookie 翻譯於 5個月前
 
由  Summer 審閱
 

定制動作##

除了之前介紹的內建動作,還可以通過提供實現 Action API 的對象來定義自定義動作。傳遞給 add_argument() 作為 action 的對象應該接受被定義參數的所有參數(也就是傳遞給 add_argument 的所有參數)並返回一個可調用對象,這個可調用對象接收 parser 作為參數解析器,namespace 持有參數解析結果,value 為參數值,和觸發動作的 option_string

一個 Action 類提供了定義新動作的便捷起點。Action 的構造器會處理參數定義,所以子類只需要重寫 __call__()

argparse_custom_action.py

import argparse class CustomAction(argparse.Action): def __init__(self, option_strings, dest, nargs=None, const=None, default=None, type=None, choices=None, required=False, help=None, metavar=None): argparse.Action.__init__(self, option_strings=option_strings, dest=dest, nargs=nargs, const=const, default=default, type=type, choices=choices, required=required, help=help, metavar=metavar, ) print('Initializing CustomAction') for name, value in sorted(locals().items()): if name == 'self' or value is None: continue print(' {} = {!r}'.format(name, value)) print() return def __call__(self, parser, namespace, values, option_string=None): print('Processing CustomAction for {}'.format(self.dest)) print(' parser = {}'.format(id(parser))) print(' values = {!r}'.format(values)) print(' option_string = {!r}'.format(option_string)) # 對輸入值做一些處理 if isinstance(values, list): values = [v.upper() for v in values] else: values = values.upper() # 以傳遞給構造器的目標變量保存結果 # variable given to our constructor. setattr(namespace, self.dest, values) print() parser = argparse.ArgumentParser() parser.add_argument('-a', action=CustomAction) parser.add_argument('-m', nargs='*', action=CustomAction) results = parser.parse_args(['-a', 'value', '-m', 'multivalue', 'second']) print(results) 

value 的類型取決於 nargs 的值。如果參數運行多重值,value 將會是一個列表即使它只包含一個元素。

option_string 的值同樣決定於原始參數定義。對於位置參數,option_string 一直是 None

$ python3 argparse_custom_action.py Initializing CustomAction dest = 'a' option_strings = ['-a'] required = False Initializing CustomAction dest = 'm' nargs = '*' option_strings = ['-m'] required = False Processing CustomAction for a parser = 4315836992 values = 'value' option_string = '-a' Processing CustomAction for m parser = 4315836992 values = ['multivalue', 'second'] option_string = '-m' Namespace(a='VALUE', m=['MULTIVALUE', 'SECOND']) 

另見#

#


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM