繁体   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