argparse:所需组中的一些互斥参数
argparse: some mutually exclusive arguments in required group
我有一组论据,在逻辑上可以分成两组:
- 操作:
A1
、A2
、A3
等
- 信息:
I1
、I2
、I3
等
程序启动至少需要这些参数之一,但 "information" 参数可以与 "action" 参数一起使用。所以
- 操作或信息中至少需要一项
- 所有操作都是互斥的
我找不到使用 argparse 的方法。我知道 add_mutually_exclusive_group
及其 required
参数,但我不能在 "Actions" 上使用它,因为实际上不需要它。当然,我可以在 argparse 之后添加一个条件来手动检查我的规则,但这似乎是一种 hack。 argparse 可以做到这一点吗?
编辑:抱歉,这里有一些例子。
# Should pass
--A1
--I1
--A1 --I2
--A2 --I1 --I2
# Shouldn't pass
--A1 --A2
--A1 --A2 --I1
我错过了什么,或者你只是想要:
import argparse
import os
def main():
parser = argparse.ArgumentParser()
actions = parser.add_mutually_exclusive_group()
actions.add_argument("-A1", action="store_true")
actions.add_argument("-A2", action="store_true")
actions.add_argument("-A3", action="store_true")
low = int(os.environ.get('LOWER_BOUNDS', 0))
high = int(os.environ.get('UPPER_BOUNDS', 3)) + 1
infos = parser.add_argument_group()
for x in range(low, high):
infos.add_argument("-I" + str(x), action="store_true")
args = parser.parse_args()
if not any(vars(args).values()):
parser.error('No arguments provided.')
print args
if __name__ == '__main__':
main()
输出:
$ python test.py
usage: test.py [-h] [-A1 | -A2 | -A3] [-I0] [-I1] [-I2] [-I3]
test.py: error: No arguments provided.
$ python test.py -A1
Namespace(A1=True, A2=False, A3=False, I1=False, I2=False, I3=False)
$ python test.py -A1 -A2
usage: test.py [-h] [-A1 | -A2 | -A3] [-I1] [-I2] [-I3]
test.py: error: argument -A2: not allowed with argument -A1
$ python test.py -A1 -I1
Namespace(A1=True, A2=False, A3=False, I1=True, I2=False, I3=False)
$ python test.py -A1 -I1 -I2
Namespace(A1=True, A2=False, A3=False, I1=True, I2=True, I3=False)
$ python test.py -A1 -I1 -I2 -I3
Namespace(A1=True, A2=False, A3=False, I1=True, I2=True, I3=True)
$ UPPER_BOUNDS=40 python test.py -A1 -I1 -I2 -I40
Namespace(A1=True, A2=False, A3=False, I0=False, I1=True, I10=False, I11=False, I12=False, I13=False, I14=False, I15=False, I16=False, I17=False, I18=False, I19=False, I2=True, I20=False, I21=False, I22=False, I23=False, I24=False, I25=False, I26=False, I27=False, I28=False, I29=False, I3=False, I30=False, I31=False, I32=False, I33=False, I34=False, I35=False, I36=False, I37=False, I38=False, I39=False, I4=False, I40=True, I5=False, I6=False, I7=False, I8=False, I9=False)
PS。我真的不建议这种 "unlimited" -I#
方法..但这里有一个例子。
在参数被解析后验证参数没有任何问题。只需将它们全部收集在一个集合中,然后确认它不为空并且最多包含一个动作。
actions = {"a1", "a2", "a3"}
informations = {"i1", "i2", "i3"}
p = argparse.ArgumentParser()
# Contents of actions and informations contrived
# to make the example short. You may need a series
# of calls to add_argument to define the options and
# constants properly
for ai in actions + informations:
p.add_argument("--" + ai, action='append_const', const=ai, dest=infoactions)
args = p.parse_args()
if not args.infoactions:
p.error("At least one action or information required")
elif len(actions.intersection(args.infoactions)) > 1:
p.error("At most one action allowed")
mutually_exclusive_group
是一个简单的 xor
逻辑测试。您可以定义 2 个单独的组,但它不提供任何工作方式across/between 组。
我已经开发了一个补丁来允许更复杂的逻辑和嵌套组。测试逻辑并没有那么糟糕,但是设计一个好的用户界面是很棘手的,创建一个有意义的 usage
行也是如此。因此,该增强功能可能永远不会投入生产。
解析后测试参数非常好。如果您无法区分具有默认值的属性和使用给您的属性,它只会变得棘手 - 所以默认默认值 None
是最好的。 argparse
主要是一个解析器,弄清楚用户想要什么。他们是否想要合法的东西(除了最简单的情况)是另一个问题。
我有一组论据,在逻辑上可以分成两组:
- 操作:
A1
、A2
、A3
等 - 信息:
I1
、I2
、I3
等
程序启动至少需要这些参数之一,但 "information" 参数可以与 "action" 参数一起使用。所以
- 操作或信息中至少需要一项
- 所有操作都是互斥的
我找不到使用 argparse 的方法。我知道 add_mutually_exclusive_group
及其 required
参数,但我不能在 "Actions" 上使用它,因为实际上不需要它。当然,我可以在 argparse 之后添加一个条件来手动检查我的规则,但这似乎是一种 hack。 argparse 可以做到这一点吗?
编辑:抱歉,这里有一些例子。
# Should pass
--A1
--I1
--A1 --I2
--A2 --I1 --I2
# Shouldn't pass
--A1 --A2
--A1 --A2 --I1
我错过了什么,或者你只是想要:
import argparse
import os
def main():
parser = argparse.ArgumentParser()
actions = parser.add_mutually_exclusive_group()
actions.add_argument("-A1", action="store_true")
actions.add_argument("-A2", action="store_true")
actions.add_argument("-A3", action="store_true")
low = int(os.environ.get('LOWER_BOUNDS', 0))
high = int(os.environ.get('UPPER_BOUNDS', 3)) + 1
infos = parser.add_argument_group()
for x in range(low, high):
infos.add_argument("-I" + str(x), action="store_true")
args = parser.parse_args()
if not any(vars(args).values()):
parser.error('No arguments provided.')
print args
if __name__ == '__main__':
main()
输出:
$ python test.py
usage: test.py [-h] [-A1 | -A2 | -A3] [-I0] [-I1] [-I2] [-I3]
test.py: error: No arguments provided.
$ python test.py -A1
Namespace(A1=True, A2=False, A3=False, I1=False, I2=False, I3=False)
$ python test.py -A1 -A2
usage: test.py [-h] [-A1 | -A2 | -A3] [-I1] [-I2] [-I3]
test.py: error: argument -A2: not allowed with argument -A1
$ python test.py -A1 -I1
Namespace(A1=True, A2=False, A3=False, I1=True, I2=False, I3=False)
$ python test.py -A1 -I1 -I2
Namespace(A1=True, A2=False, A3=False, I1=True, I2=True, I3=False)
$ python test.py -A1 -I1 -I2 -I3
Namespace(A1=True, A2=False, A3=False, I1=True, I2=True, I3=True)
$ UPPER_BOUNDS=40 python test.py -A1 -I1 -I2 -I40
Namespace(A1=True, A2=False, A3=False, I0=False, I1=True, I10=False, I11=False, I12=False, I13=False, I14=False, I15=False, I16=False, I17=False, I18=False, I19=False, I2=True, I20=False, I21=False, I22=False, I23=False, I24=False, I25=False, I26=False, I27=False, I28=False, I29=False, I3=False, I30=False, I31=False, I32=False, I33=False, I34=False, I35=False, I36=False, I37=False, I38=False, I39=False, I4=False, I40=True, I5=False, I6=False, I7=False, I8=False, I9=False)
PS。我真的不建议这种 "unlimited" -I#
方法..但这里有一个例子。
在参数被解析后验证参数没有任何问题。只需将它们全部收集在一个集合中,然后确认它不为空并且最多包含一个动作。
actions = {"a1", "a2", "a3"}
informations = {"i1", "i2", "i3"}
p = argparse.ArgumentParser()
# Contents of actions and informations contrived
# to make the example short. You may need a series
# of calls to add_argument to define the options and
# constants properly
for ai in actions + informations:
p.add_argument("--" + ai, action='append_const', const=ai, dest=infoactions)
args = p.parse_args()
if not args.infoactions:
p.error("At least one action or information required")
elif len(actions.intersection(args.infoactions)) > 1:
p.error("At most one action allowed")
mutually_exclusive_group
是一个简单的 xor
逻辑测试。您可以定义 2 个单独的组,但它不提供任何工作方式across/between 组。
我已经开发了一个补丁来允许更复杂的逻辑和嵌套组。测试逻辑并没有那么糟糕,但是设计一个好的用户界面是很棘手的,创建一个有意义的 usage
行也是如此。因此,该增强功能可能永远不会投入生产。
解析后测试参数非常好。如果您无法区分具有默认值的属性和使用给您的属性,它只会变得棘手 - 所以默认默认值 None
是最好的。 argparse
主要是一个解析器,弄清楚用户想要什么。他们是否想要合法的东西(除了最简单的情况)是另一个问题。