Python的argparse模块中可选的位置参数

9
尝试解析可选的位置参数时,我遇到了以下问题:
示例:
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('infile')
parser.add_argument('outfile', nargs='?')
parser.add_argument('-v', action='store_true')

print(parser.parse_args())

输出:

$ ./x.py -v in out
Namespace(infile='in', outfile='out', v=True)

$ ./x.py in out -v
Namespace(infile='in', outfile='out', v=True)

$ ./x.py in -v out
usage: x.py [-h] [-v] infile [outfile]
x.py: error: unrecognized arguments: out

第三次程序调用为何无法接受?这是argparse的限制吗?
1个回答

10
这是argparse的一个限制,但在3.7中部分解除了这个限制。
Unix工具通常不支持选项和参数的混合使用,尽管它们经常这样做。问题在于将其与其他一些特性(如子命令)结合使用会导致歧义。因此,通常支持任何这些特性的库都会避开这个问题并且不允许混合使用。或者他们会做一些有点hacky的事情——允许在末尾、开头和某些难以预测的情况下使用选项,但在中间却不能使用。
这就是argparse最初所做的事情。但是3.7添加了Intermixed parsing
您必须手动调用parse_intermixed_args而不是parse_args
如果您尝试将其与任何不兼容的特性一起使用,则会收到异常(即使对于您传递的特定args集合没有歧义,这应该更容易调试)。
但否则,它将按预期工作:选项(当然还包括它们的值)可以自由地与命令行中的位置参数混合使用。

很遗憾,我不知道在PyPI上有没有一个即插即用的回溯方法可以在早期版本中得到3.7 argparse; 半官方的argparse回溯主要是针对完全没有它的2.7 / 3.2版本,并且仅回溯到3.4版本。


我明白了,这被称为交错解析。很好知道,谢谢。我刚安装了Python 3.7,在那里它运行得很顺畅。 - Andreas Matthias
argparse.py 文件来自 3.7 存储库,可与早期的 Py3 发行版一起使用。只需将其复制到您自己的目录中,可能会重命名,然后导入即可。 - hpaulj
@hpaulj 这个能向后兼容到哪个版本?(即使需要3.4,这对很多人来说可能不是障碍,但如果它能够向后兼容到3.1或3.0,那就太好了。) - abarnert
我不知道。我知道在Py3版本中有一个yield from行,防止在Py2下使用。我不记得还有其他的问题。我只安装了3.6,所以无法进一步测试它。 - hpaulj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接