如何修改Python argparse中位置参数的metavar?
在 argparse 这个包里,metavar
参数用来修改程序显示的帮助信息。下面这个程序并不是为了实际运行,而是用来演示 metavar
参数的行为。
import argparse
if __name__ == '__main__':
parser = argparse.ArgumentParser(description = "Print a range.")
parser.add_argument("-range1", nargs = 3, type = int, help = "Specify range with: start, stop, step.", metavar = ("start", "stop", "step"))
parser.add_argument("-range2", nargs = 3, type = int, help = "Specify range with: start, stop, step.", metavar = "r2")
对应的帮助信息是:
usage: main.py [-h] [-range1 start stop step] [-range2 r2 r2 r2]
Print a range.
optional arguments:
-h, --help show this help message and exit
-range1 start stop step
Specify range with: start, stop, step.
-range2 r2 r2 r2 Specify range with: start, stop, step.
请注意 -range1
和 -range2
之间的区别。显然,-range1
是帮助信息中更推荐的写法。
到目前为止我都能理解。但是,如果我把可选的 -range1
参数改成一个位置参数 range1
,那么 argparse 就无法处理 metavar
参数的元组了(会出现 ValueError: too many values to unpack
的错误)。
我唯一能让它工作的方式就是像 -range2
那样做。但那样的话,帮助信息就远不如 -range1
的情况好。
有没有办法让位置参数的帮助信息和 -range1
一样好,而不是像可选参数那样呢?
2 个回答
不过,如果我把可选的-range1参数改成位置参数range1,argparse就无法处理metavar参数的元组了(ValueError: 值太多,无法拆分)。
argparse不应该出现这个“值太多,无法拆分”的错误信息。这个错误是由metavar, = self._metavar_formatter(action, default)(1)
产生的。通常这个函数会返回一个单一的列表或元组,但在你的情况下,它返回了一个元组metavar。它应该给出更清晰的错误信息(比如位置参数不允许使用元组metavar
?),或者优雅地调整metavar(比如start|stop|step
?)。另一种选择是在帮助信息中使用默认的metavar,而不是元组。
元组metavar在使用行上是可以正常工作的。
我觉得帮助信息的格式是考虑到统一的位置参数来写的。在使用行上可能会显示X [X [X ...]]
,但在帮助行上只显示X ... X的描述
。
你的三个项目有不同的名称,所以unutbu建议的三个独立的位置参数,可能正是argparse设计者的初衷。
这个问题已经被提出来了(但还没有修复)
http://bugs.python.org/issue14074 “argparse允许位置参数的nargs>1,但不允许metavar是一个元组”
这样怎么样:
import argparse
if __name__ == '__main__':
parser = argparse.ArgumentParser(description = "Print a range.")
parser.add_argument("start", type = int, help = "Specify start.", )
parser.add_argument("stop", type = int, help = "Specify stop.", )
parser.add_argument("step", type = int, help = "Specify step.", )
args=parser.parse_args()
print(args)
这样会得到:
% test.py -h
usage: test.py [-h] start stop step
Print a range.
positional arguments:
start Specify start.
stop Specify stop.
step Specify step.
optional arguments:
-h, --help show this help message and exit