我想知道是否有可能使用可选参数的参数跟随位置参数。理想情况下,输入命令行的最后一个参数将始终应用于'testname'。
import argparse
parser = argparse.ArgumentParser(description='TAF')
parser.add_argument('-r','--release',nargs='?',dest='release',default='trunk')
parser.add_argument('testname',nargs='+')
args = parser.parse_args()
我希望这两个调用都能将smoketest应用于testname,但第二个调用会导致错误。
>> python TAF.py -r 1.0 smoketest
>> python TAF.py -r smoketest
TAF.py: error: too few arguments
我意识到将位置参数移动到前面会导致可选参数的正确行为,但这不是我正在寻找的格式。选择标志看起来像一个有吸引力的替代方案,但它会抛出错误而不是忽略不匹配的项目。
编辑: 我找到了一个围绕这个的hacky方式。如果有人有更好的解决方案我会很感激。
import argparse
parser = argparse.ArgumentParser(description='TAF')
parser.add_argument('-r','--release',nargs='?',dest='release',default='trunk')
parser.add_argument('testname',nargs=argparse.REMAINDER)
args = parser.parse_args()
if not args.testname:
args.testname = args.release
args.release = ''
答案 0 :(得分:4)
如documentation中所述:
'?'
。如果可能,将从命令行使用一个参数, 并作为单个项目生产。如果不存在命令行参数, 将生成默认值。请注意,对于可选 参数,还有一个例子 - 选项字符串存在 但后面没有命令行参数。在这种情况下的价值 来自const将会产生。
因此,使用'?'
无法获得所需的行为。可能你可以使用argparse.Action
编写一些hack并干预之前的结果。(1)
我认为更好的解决方案是拆分该选项的功能。使它成为一个需要参数的选项(但选项本身是可选的)并添加一个不带参数的选项,将版本设置为'trunk'
。通过这种方式,您可以获得相同的结果,而无需任何黑客攻击。我认为界面更简单。
在你的例子中:
python TAF.py -r smoketest
很明显,smoketest
将被解释为-r
的参数。至少遵循unix约定。如果您想保留nargs='?'
,则用户必须使用--
:
$ python TAF.py -r -- sometest
Namespace(release=None, testname=['sometest']) #parsed result
(1)关于如何执行此操作的想法:检查选项是否有参数。如果有一个检查它是否是有效的测试名称。如果是这样,请手动插入testname
并将release
设置为默认值。你还必须设置一个“标志”,告诉你这件事发生了。
现在,在解析sys.argv
之前,您必须重定向sys.stderr
。在进行解析时,您必须捕获SystemExit
,检查stderr
并查看错误是否“参数太少”,检查是否设置了标志,如果是,请忽略错误并继续运行,否则您应重新打印到原始stderr
错误消息并退出。
这种方法看起来并不健壮,而且可能是错误的。