2

我有测试场景,我需要根据传递给 python 脚本的参数采取行动。要求如下:

test.py -a a1 -b b1 [[[-c c1] [-d d1]] | [-e e1 -f f1]]

  1. 用户必须传递强制参数“-a”和“-b”。
  2. 参数“-c”和“-d”是可以单独传递的可选参数。
  3. 参数“-e”和“-f”是可选参数,必须与强制参数一起传递。
  4. 如果“-c”或“-d”中的任何一个与“-e”和“-f”一起传递,那么脚本应该为参数“-c”或“-d”给出错误。
  5. 如果“-e”和“-f”与“-c”或“-d”一起传递,那么脚本应该为参数“-e”和“-d”给出错误。

该错误可能是所有可选参数的一般错误。

到目前为止,我正在尝试使用parents=选项来执行此操作,argparse.ArgumentParser但是当我尝试读取传递的参数时它会出错。

import argparse


parent_parser = argparse.ArgumentParser(add_help=False)
parent_parser.add_argument('-a', type=str, required=True)
parent_parser.add_argument('-b', type=str, required=True)

one_parser = argparse.ArgumentParser(parents=[parent_parser])
one_parser.add_argument('-c', type=str, default="test")
one_parser.add_argument('-d', type=str, default="Default")

multi_parser = argparse.ArgumentParser(parents=[parent_parser])
multi_parser.add_argument('-e', type=str)
multi_parser.add_argument('-f', type=str)

if str(one_parser.parse_args().c):
    print(one_parser.parse_args())
elif str(multi_parser.parse_args().e):
    print(multi_parser.parse_args())

当我将脚本运行为:

test.py -a a1 -b b1 -e e1 -f f1

我收到错误:

usage: test.py [-h] -a A -b B [-c C] [-d D]
test.py: error: unrecognized arguments: -e e1 -f f1

Process finished with exit code 2

任何指针都受到高度赞赏。谢谢你。

答: 解决方案是 hack,但它对我有用。

import argparse


parser = argparse.ArgumentParser(add_help=False)
parser.add_argument('-a', type=str, required=True)
parser.add_argument('-b', type=str, required=True)
parser.add_argument('-c', type=str)
parser.add_argument('-d', type=str)
parser.add_argument('-e', type=str)
parser.add_argument('-f', type=str)
args = parser.parse_args()

a = str(args.a)
b = str(args.b)
c = str(args.c)
d = str(args.d)
e = str(args.e)
f = str(args.f)

if (e != "None" and f == "None") or (e == "None" and f != "None"):
    if c == "None" and d == "None":
        raise argparse.ArgumentTypeError("Both e and f arguments are required")
    elif c != "None" or d != "None":
        raise argparse.ArgumentTypeError("e and f are not supported with c or d")
if (c != "None" or d != "None") and (e != "None" or f != "None"):
    raise argparse.ArgumentTypeError("c and d are not supported with e and f")
if e == "None" and f == "None":
    if c == "None":
        c = "test"
    if d == "None":
        d = "Default"

IMO,argparser 应该更有效地处理参数依赖。也许有人会贡献并帮助我们所有人.. :)

4

1 回答 1

1

您的问题是使用多个解析器,参数组可能会对您有所帮助。

然后,您必须检查自己的参数是否符合您的条件,并在必要时引发 argparse.ArgumentError。

这是一个可以解决问题的代码示例。arguments_group 仅用于记录 -h 参数(argparser 帮助)

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("-a", required=True)
parser.add_argument("-b", required=True)
first = parser.add_argument_group("group 1", "None, one or both")
first.add_argument("-c")
first.add_argument("-d")
second = parser.add_argument_group("group 2", "None or both")
second.add_argument("-e")
second.add_argument("-f")

args = parser.parse_args()

a = args.a
b = args.b
c = args.c
d = args.d
e = args.e
f = args.f

if (e is not None and f is None) or (e is None and f is not None):
    if c is None and d is None:
        raise argparse.ArgumentError("Both e and f arguments are required")
    elif c is None or d is not None:
        raise argparse.ArgumentError("e and f are not supported with c or d")
if (c is not None or d is not None) and (e is not None or f is not None):
    raise argparse.ArgumentError("c and d are not supported with e and f")
于 2020-01-09T14:01:40.687 回答