簡體   English   中英

如何讓 Python argparse 接受“-a”標志代替位置參數?

[英]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會自動考慮以-開頭的字符串作為參數

位置參數只能以-開頭,如果它們看起來像負數並且解析器中沒有看起來像負數的選項。

因此,如果您將關鍵字更改為allign ,則可以執行以下操作:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM