Python argparse余数不清楚
如文件所示: argparse.rements。所有剩余的命令行参数都收集到一个列表中。这对于分派到其他命令行实用程序的命令行实用程序通常很有用: 我试图将其用于完全相同的目的,但在某些情况下,它对我来说似乎有问题(或者可能我的概念错了): 结果:Python argparse余数不清楚,python,arguments,argparse,Python,Arguments,Argparse,如文件所示: argparse.rements。所有剩余的命令行参数都收集到一个列表中。这对于分派到其他命令行实用程序的命令行实用程序通常很有用: 我试图将其用于完全相同的目的,但在某些情况下,它对我来说似乎有问题(或者可能我的概念错了): 结果: test.py: error: ambiguous option: -q could match -qa, -qb $ ./testcmd -qsomething test ./otherutil bar -q atr q: -qsomething
test.py: error: ambiguous option: -q could match -qa, -qb
$ ./testcmd -qsomething test ./otherutil bar -q atr
q: -qsomething
extra: "test ./otherutil bar -q atr"
因此,显然,如果otherutil
的参数与argparse
的参数存在某种程度的“冲突”,那么它似乎无法正常工作
我希望当
argparse
到达rements
类型的参数时,它只使用列表末尾的所有字符串,而不进行任何进一步的解析。我能以某种方式达到这种效果吗?您需要使用两个--
a.add_argument('--qa', nargs='?')
a.add_argument('--qb', nargs='?')
因此,您定义的选项与-q
冲突,后者至少接受在其他地方定义的参数
从
编辑以回复@PDani第一条评论:
这很有趣
据我所知,argparse遵循POSIX和GNU风格
重要的是,短(1个字母)选项可以组合在一起,如果一个选项需要一个参数,则可以将其附加到选项字母上。例如,如果你有这样的东西
a.add_argument('-a', action='store_true')
a.add_argument('-b', action='store_true')
a.add_argument('-c', action='store_true')
a.add_argument('-d', nargs=1)
a.add_argument('-e', nargs=1)
您可以将它们称为-abcd3-e5
或-a-b-c-d3-e5
或-cba-e5-d3
,…现在,如果你有
a.add_argument('-abc', action='store_true')
你有
argparse很难确定-abc
是附加了3个短参数还是一个长参数。因此,您必须将参数定义为--abc
因此,我想您不能将长参数名称与一个-
一起使用
a.add_argument('--qa', nargs='?')
a.add_argument('--qb', nargs='?')
我知道另一种做命令行解析的方法,叫做:你可以看一下,但我怀疑它能否解决你的问题 也许是一些特殊处理的组合 这并不完美,但可能会朝着正确的方向发展:
import argparse
import sys
a = argparse.ArgumentParser()
# treat the common-prefixed arguments as options to the prefix
a.add_argument("-q")
# allow a delimiter to set off your arguments from those which should go to the
# other utility, and use parse_known_args() if the delimiter is not present
argv = sys.argv[1:]
if "--" in argv:
i = argv.index("--")
args, extra = a.parse_args(argv[:i]), argv[i + 1:]
else:
a.add_argument("extra", nargs=argparse.REMAINDER)
args, _ = a.parse_known_args(argv)
extra = args.extra
# complain if the `-q` option was not specified correctly
if args.q not in ("something", "otherthing"):
a.error("Must specify '-qsomething' or '-qotherthing'")
print "q:", "-q%s" % (args.q,)
print "extra:", '"%s"' % (" ".join(extra),)
结果:
test.py: error: ambiguous option: -q could match -qa, -qb
$ ./testcmd -qsomething test ./otherutil bar -q atr
q: -qsomething
extra: "test ./otherutil bar -q atr"
注意事项:
-q
和-q
前缀选项的其余部分之间留出一个空格-q
选项,但我不记得如果指定更多,它是否会引发异常(或执行任何其他有用的操作)我在尝试向底层实用程序分派选项时遇到了这个问题。我最后使用的解决方案是
nargs='*'
,而不是nargs=argparse.rements
,然后只需使用“伪参数”--
来分隔我的命令和底层工具的选项:
>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--myflag', action='store_true')
>>> parser.add_argument('toolopts', nargs='*')
>>> parser.parse_args('--myflag -- -a --help'.split())
Namespace(myflag=True, toolopts=['-a', '--help'])
这很容易记录在帮助输出中。这更多地与缩写的处理有关,而不是与其余的
nargs
有关
In [111]: import argparse
In [112]: a = argparse.ArgumentParser()
...:
...: a.add_argument('-qa', nargs='?')
...: a.add_argument('-qb', nargs='?')
In [113]: a.parse_args('-qa test ./otherutil bar -q atr'.split())
usage: ipython3 [-h] [-qa [QA]] [-qb [QB]]
ipython3: error: ambiguous option: -q could match -qa, -qb
argparse
执行2次解析。首先,它尝试将字符串分类为选项(标志)或参数。其次,它交替解析位置和选项,根据nargs
分配参数
In [111]: import argparse
In [112]: a = argparse.ArgumentParser()
...:
...: a.add_argument('-qa', nargs='?')
...: a.add_argument('-qb', nargs='?')
In [113]: a.parse_args('-qa test ./otherutil bar -q atr'.split())
usage: ipython3 [-h] [-qa [QA]] [-qb [QB]]
ipython3: error: ambiguous option: -q could match -qa, -qb
在这里,歧义发生在第一遍。它试图将'-q'与两个可用选项匹配。余数的特殊动作(吸收'-q',就好像它是一个普通字符串)直到第二次传递才发生
较新的argparse
版本允许我们关闭缩写处理:
In [114]: a.allow_abbrev
Out[114]: True
In [115]: a.allow_abbrev=False
In [116]: a.parse_args('-qa test ./otherutil bar -q atr'.split())
usage: ipython3 [-h] [-qa [QA]] [-qb [QB]]
ipython3: error: unrecognized arguments: ./otherutil bar -q atr
如果我加上余数动作:
In [117]: a.add_argument('rest', nargs=argparse.REMAINDER)
In [118]: a.parse_args('-qa test ./otherutil bar -q atr'.split())
Out[118]: Namespace(qa='test', qb=None, rest=['./otherutil', 'bar', '-q', 'atr'])
@Colin建议使用“---”是可行的,因为该字符串在第一次传递时被识别:
In [119]: a.allow_abbrev=True
In [120]: Out[117].nargs='*'
In [121]: a.parse_args('-qa test -- ./otherutil bar -q atr'.split())
Out[121]: Namespace(qa='test', qb=None, rest=['./otherutil', 'bar', '-q', 'atr'])
如果我理解正确,argparse无法处理两个字母的“短参数”?实际上,我的目标是用argparse模拟现有命令行工具的行为,它使用诸如“-qsomething”和“-qotherthing”(其中something和otherthing不是可选参数)之类的选项。2021年支持的方法是:
parser.add_参数(“-q”,dest=“qq”,choices=[“something”,“otherthing”)
Old-question,但将test添加为子解析器应该可以解决这个问题。然后,它的-q将由该子解析器而不是顶级解析器处理。我也会使用--qa和--qb这对我帮助很大。在传递到argparse之前,在'-'
上进行拆分非常有意义。我正要去处理海关行动等。谢谢。