首页 > 解决方案 > Python argparse 的可选位置参数

问题描述

试图解析可选的位置参数我遇到了以下问题:

例子:

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

标签: pythonargparse

解决方案


这是 argparse 的一个限制——但在 3.7 中已部分取消。

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

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

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

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

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


不幸的是,我不知道 PyPI 上有一个可以argparse在早期版本中获得 3.7 的嵌入式反向移植。半官方的argparsebackport主要针对pre-2.7/3.2的版本根本没有,只backport 3.4的版本。


推荐阅读