Python 的 argparse 的可选位置参数

Optional positional arguments with Python's argparse

正在尝试将可选位置参数 I 运行 解析为以下问题:

示例:

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的限制吗?

这是 argparse 的一个限制——但在 3.7 中部分解除了。

Unix 工具通常不声称支持选项和参数的混合,尽管它们经常这样做。问题是将它与其他一些功能(如子命令)结合使用会导致歧义。因此,通常情况下,支持任何这些功能的库都会解决这个问题并且不允许混合。或者他们会做一些 hacky——在结尾、开头和某些难以预测的情况下允许选项,但在中间的其他情况下则不允许。

argparse 最初就是这样做的。但是3.7增加了Intermixed parsing.

您必须手动调用 parse_intermixed_args 而不是 parse_args

如果您尝试将它与它不适合的任何功能一起使用,您将得到一个例外(即使您传递的特定参数集没有歧义——这应该使它成为更容易调试)。

但除此之外,它将按预期工作:选项(当然连同它们的值)可以在命令行中的任何位置自由地与位置参数混合。


不幸的是,我不知道 PyPI 上的直接向后移植可以在早期版本中获得 3.7 argparse;半官方argparse backport 主要针对完全没有它的pre-2.7/3.2 版本,只backport 3.4 版本。