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.