Python Argparse和几个排他参数

Python Argparse和几个排他参数,python,argparse,Python,Argparse,我试图在python中实现Caesar密码,并使用argparse解析参数 但是,我不知道如何创建以下几个排他参数: caesar.py ,- '-b' / '-d' --- xor / \ xor `- '-k key' \ '-e' --- '-k key' 必须指定-d或-e(专用) 如果指定-e,则必须指定-k-b是禁止的 如果指定-d,则必须指定-k或-

我试图在
python
中实现Caesar密码,并使用
argparse
解析参数

但是,我不知道如何创建以下几个排他参数:

caesar.py        ,-   '-b'
                /
    '-d' --- xor
   /            \
 xor             `-   '-k key'
   \
    '-e' ---  '-k key'
  • 必须指定
    -d
    -e
    (专用)

  • 如果指定
    -e
    ,则必须指定
    -k
    <代码>-b是禁止的

  • 如果指定
    -d
    ,则必须指定
    -k
    -b
    (专用)

  • 这是我做的:

    parser = argparse.ArgumentParser(description="Caesar Cipher")
    
    parser.add_argument("text", nargs="?", help="message to encode/decode")
    
    parser_code = parser.add_mutually_exclusive_group(required=True)
    parser_code.add_argument("-e", action="store_true", help="encode")
    parser_code.add_argument("-d", action="store_true", help="decode")
    
    parser_decode = parser.add_mutually_exclusive_group(required=True)
    parser_decode.add_argument('-k', type=int, dest="key",   help="key to use")
    parser_decode.add_argument('-b', action="store_true" help="bruteforce the key")
    
    args = parser.parse_args()
    
    实际上,它不起作用。事实上,我仍然可以使用:

    python caesar.py -e -b message
    

    选项
    -b
    应该没有意义。我知道我可以简单地进行检查并调用
    parser.print_help()
    ,但是我希望在解析过程中进行此检查,例如独占检查

    我认为,
    argparse
    没有任何条款允许您的情况。我能想到的最好方法是使用子解析器:

    caesar.py: 示例用法:
    argparse
    做一些原本不该做的事情,这是一种好的编程设计吗

    您已经定义了两组互斥的参数,实际上是对其发生情况的
    xor
    测试。但是
    argparse
    不实现嵌套。我认为你可以把这两个组放在另一个相互排斥的组中,但最终的效果是把所有的参数放在一个大组中——也就是说,只允许整个组中的一个

    我在一个bug/问题中探讨了实现嵌套的想法,以及可以实现任何类型逻辑关系(xor,或(=any)和(=all)的组。但这是一个复杂的加法。更麻烦的一个方面是在用法显示中格式化嵌套关系。简单的互斥组已经够麻烦的了

    您如何向用户解释允许哪些参数组合

    我认为您最好的选择是明智地定义默认值,这样您就可以清楚地知道哪些参数已经给出,哪些没有给出,然后在解析后执行测试

    对于“store_true”参数,您可以只测试名称空间属性的真值。对于存储值的参数,测试
    is None
    通常是一个很好的指标。用户不能提供
    None
    值,因此
    args.dest is None
    显然意味着未使用该参数

    因此,只需编写嵌套的
    if
    测试:

    if args.one and args.two is None:
        if args.three is not None:
            parser.error('three cannot occur with one and two')
    etc.
    

    argparse
    最好被看作是一个解析器,它可以找出用户想要什么。您可以使用
    argparse
    执行一些简单的测试,并在某些参数组合不兼容时通知用户。但它不应该是测试和使用参数的主要工具。您自己的代码应该具有最终响应考虑到
    -k
    -encode
    唯一合法的“选项”并且是必需的,我将删除它,并将其作为另一个位置参数:
    caesar encode 5
    。对于
    解码
    -k
    -b
    应该是一个相互排斥的组的成员,如原问题所述。
    ./caesar.py encode -k 5
    ./caesar.py decode -k 9 -b
    
    if args.one and args.two is None:
        if args.three is not None:
            parser.error('three cannot occur with one and two')
    etc.