![](/img/trans.png)
[英]Python Argparse: how to make an argument required if and only if one flag is given?
[英]How to make Python argparse accept a "-a" flag in place of the positional argument?
我正在使用 argparse 編寫 Python 程序。 我有一個 ID 值的參數。 用戶可以在程序中指定要處理的 ID 值。 或者他們可以指定 -a 來指定應該處理所有 ID。
因此,以下兩項都應該有效:
myprog 5
myprog -a
但是如果你沒有指定一個特定的 ID,那么 -a 是必需的,它應該拋出一個錯誤。
我玩過一個相互排斥的群體:
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('-a', action='store_true', help=argparse.SUPPRESS)
group.add_argument("ID", action='store', nargs='?')
哪個有效,但我解析的參數最終是兩個參數:
{'a': True, 'ID': None}
如果我嘗試在此之后添加一個類似的組,請說另一個參數“max”可以是最大值或 -i 表示忽略最大值:
group2 = parser.add_mutually_exclusive_group(required=True)
group2.add_argument('-i', action='store_true', help=argparse.SUPPRESS)
group2.add_argument("max", action='store', nargs='?')
然后,如果我嘗試解析參數 ['-a', '2'] 它會拋出一個錯誤說:
usage: args_exclusive_group.py [-h] [ID] [max]
args_exclusive_group.py: error: argument ID: not allowed with argument -a
因為它將 2 視為 ID 而不是最大值。 是否有一些我遺漏的非常簡單的東西,它只允許指定的位置參數(ID 或 max)也接受一個恰好“看起來像”可選的字符串,因為它以“-”開頭?
如果您想將其保留為 2 個位置參數,一種方法可能是將-a
和-i
標志封裝在它們各自的參數中並進行一些后處理。 問題在於argparse
會自動考慮以-
開頭的字符串作為參數:
位置參數只能以
-
開頭,如果它們看起來像負數並且解析器中沒有看起來像負數的選項。
因此,如果您將關鍵字更改為all
和ign
,則可以執行以下操作:
parser = argparse.ArgumentParser()
parser.add_argument("ID")
parser.add_argument("max")
args = parser.parse_args()
if args.ID == 'all':
print("processing all")
elif args.ID.isdigit():
print(f"processing {args.ID}")
else:
parser.error("ID must be a number or 'all' to use all IDs")
if args.max == 'ign':
print("ignoring max")
elif args.max.isdigit():
print(f"max is {args.max}")
else:
parser.error("max must be a number or 'ign' to disable max")
一些運行示例將是:
>>> tests.py 5 ign
processing 5
ignoring max
>>> tests.py all 7
processing all
max is 7
>>> tests.py blah 7
tests.py: error: ID must be a number or 'all' to use all IDs
>>> tests.py 5 blah
tests.py: error: max must be a number or 'ign' to disable max
如果你真的必須使用-a
和-i
:
您可以插入偽參數
'--'
,它告訴parse_args()
之后的所有內容都是位置參數
只需將解析行更改為:
import sys
...
args = parser.parse_args(['--'] + sys.argv[1:])
最簡單的方法是只有一個位置參數,其值要么是像all
這樣的特殊標記,要么是特定進程的編號。 您可以使用自定義類型處理此問題。
def process_id(s):
if s == "all":
return s
try:
return int(s)
except ValueError:
raise argparse.ArgumentTypeError("Must be 'all' or an integer")
p = argparse.ArgumentParser()
p.add_argument("ID", type=process_id)
args = p.parse_args()
if args.ID == "all":
# process everything
else:
# process just args.ID
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.