Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python argparse中的参数依赖关系_Python_Argparse_Argument Validation - Fatal编程技术网

Python argparse中的参数依赖关系

Python argparse中的参数依赖关系,python,argparse,argument-validation,Python,Argparse,Argument Validation,我有一个测试场景,需要根据传递给python脚本的参数采取操作。要求如下: test.py-a a1-b b1[[[-c c1][-d d1].[-e e1-f f1]] 用户必须传递强制参数'-a'和'-b' 参数'-c'和'-d'是可选参数,可以单独传递 参数'-e'和'-f'是可选参数,必须与必需参数一起传递 如果'-c'或'-d'中的任何一个与'-e'和'-f'一起传递,则脚本应该为参数'-c'或'-d'提供错误信息 若'-e'和'-f'与'-c'或'-d'一起传递,那个么脚本应该为参数

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

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

  • 用户必须传递强制参数'-a'和'-b'
  • 参数'-c'和'-d'是可选参数,可以单独传递
  • 参数'-e'和'-f'是可选参数,必须与必需参数一起传递
  • 如果'-c'或'-d'中的任何一个与'-e'和'-f'一起传递,则脚本应该为参数'-c'或'-d'提供错误信息
  • 若'-e'和'-f'与'-c'或'-d'一起传递,那个么脚本应该为参数'-e'和'-d'给出错误
  • 该错误可能是所有可选参数的一般错误

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

    import argparse
    parser=argparse.ArgumentParser(add\u help=False)
    parser.add_参数('-a',type=str,required=True)
    parser.add_参数('-b',type=str,required=True)
    一个语法分析器=argparse.ArgumentParser(父语法分析器=[父语法分析器])
    一个解析器。添加参数('-c',type=str,default=“test”)
    一个语法分析器。添加参数('-d',type=str,default=“default”)
    multi\u parser=argparse.ArgumentParser(parents=[parent\u parser])
    多语法分析器。添加语法参数('-e',type=str)
    多语法分析器。添加语法参数('-f',type=str)
    如果str(一个解析器.parse_args().c):
    打印(一个语法分析器。语法分析器()
    elif str(多语法分析器.parse_args().e):
    打印(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
    
    非常感谢您的指点。 多谢各位

    回答: 解决方案是黑客,但它对我有效

    import argparse
    parser=argparse.ArgumentParser(add\u help=False)
    parser.add_参数('-a',type=str,required=True)
    parser.add_参数('-b',type=str,required=True)
    parser.add_参数('-c',type=str)
    parser.add_参数('-d',type=str)
    parser.add_参数('-e',type=str)
    parser.add_参数('-f',type=str)
    args=parser.parse_args()
    a=str(args.a)
    b=str(参数b)
    c=str(args.c)
    d=str(参数d)
    e=str(参数e)
    f=str(参数f)
    如果(e!=“无”和f==“无”)或(e==“无”和f!=“无”):
    如果c==“无”和d==“无”:
    raise argparse.ArgumentTypeError(“e和f参数都是必需的”)
    以利夫c!=“无”或d!=“无”:
    raise argparse.ArgumentTypeError(“c或d不支持e和f”)
    如果(c!=“无”或d!=“无”)和(e!=“无”或f!=“无”):
    raise argparse.ArgumentTypeError(“e和f不支持c和d”)
    如果e==“无”且f==“无”:
    如果c==“无”:
    c=“测试”
    如果d==“无”:
    d=“默认值”
    

    在我看来,argparser应该更有效地处理参数依赖关系。也许有人会做出贡献,帮助我们所有人:)

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

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

    下面是一个代码示例,可以实现这一点。arguments_组仅用于记录-h参数(argparser帮助)


    您不应该使用多个解析器,而应该查看参数组1。您只需要使用一个解析器,因为如果一个解析器失败,它就会退出。就这样
    if str(one_parser.parse_args().c):
    甚至不检查
    c
    ,因为它无法识别
    -e1
    ,所以它打印帮助并退出。2.您可以手动抛出错误以进行更复杂的检查-
    raise argparse.ArgumentTypeError(“此处为您的错误消息”)
    (如果在
    中使用,请记住,您可以
    raise…from
    获取信息性错误消息!)3。辩论小组是你的朋友。它们不能做所有的事情,但是如果你做对了,你可能会得到
    [[[-c1][-dd1].[-ee1-f1]]
    部分。@PySaad它意味着-c和-d是独立的可选参数。此外,-e和-f需要一起使用,不应该与-c或-d一起使用。@NileshBhave另外,根据我尝试做类似事情的个人经验,argparse不容易(如果有)处理这种级别的参数复杂性。只需简单地说“必需”或“可选”就可以更容易地解析您的参数,然后在代码中检查是否符合您的条件,在需要时(正如h4z3所指出的那样)提出
    ArgumentTypeError
    。只需注意:这里也有
    ArgumentError
    ——这就是应该使用的参数
    ArgumentTypeError
    是关于将得到的字符串转换为实际参数值。(我只是查看了一个我解析日期的脚本,所以我需要错误的类型版本,oops。)首先,我尝试使用相同的方法。但这是行不通的。前面提到的链接显示了以下内容:
    add\u argument\u group()方法返回一个参数组对象,该对象与常规ArgumentParser一样具有add\u argument()方法。将参数添加到组中时,解析器将其视为普通参数,但将其显示在单独的组中以获取帮助消息。
    因此,简而言之,它只是一个要显示的组,但不能解决依赖性问题。是的,参数组仅用于文档。解析之后,仍然必须执行参数检查。我编辑了我的答案以添加检查部分。
    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")