【问题标题】:Tuple metavar value for positional argument with nargs > 1nargs > 1 的位置参数的元组元变量值
【发布时间】:2019-10-24 12:31:04
【问题描述】:

似乎将元组设置为metavar 用于位置参数并请求帮助不起作用:

import argparse


parser = argparse.ArgumentParser()
parser.add_argument('size', type=int, nargs=2, help='size', metavar=('w', 'h'))

args = parser.parse_args()
print(args)

当调用 prog.py --help 时会产生错误。 Python3 版本(我尝试了 3.5、3.6、3.8)之间的错误不同,包括ValueError: too many values to unpack (expected 1)TypeError: sequence item 0: expected str instance, tuple foundSee live example on Wandbox.

对于可选参数,一切都很好:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--size', type=int, nargs=2, help='size', metavar=('w', 'h'))

args = parser.parse_args()
print(args)

Live example on Wandbox.

我的代码是无效的,还是我在 Python 实现中发现了错误?

请注意,只需解析参数即可按预期工作。

【问题讨论】:

  • metavar 不是仅用于可选参数吗?
  • 不仅如此,请看official docs的例子。但是,元组元变量仅用于以下示例中的可选参数。

标签: python python-3.x argparse


【解决方案1】:

回溯的最后一部分是

/usr/lib/python3.6/argparse.py in _format_action_invocation(self, action)
    550         if not action.option_strings:
    551             default = self._get_default_metavar_for_positional(action)
--> 552             metavar, = self._metavar_formatter(action, default)(1)
    553             return metavar
    554 

所以是的,它专门发生在positionals(空option_strings)。 metavar, = ... 分配仅适用于 RHS 返回一项。使用您的metavar,它会返回 2。

使用显示正常

In [36]: parser.print_usage()                                                   
usage: ipython3 [-h] w h

它看起来确实像一个错误。

(1) 参数告诉函数应该返回一个 1 元素元组:

metavar, = self._metavar_formatter(action, default)(1)

我怀疑这个问题已经在 Python 错误/问题中提出了。我稍后再找。


您也可以使用两个位置参数来代替 metavar:

parser = argparse.ArgumentParser()
parser.add_argument('w', type=int)
parser.add_argument('h', type=int)

这是一个已知的错误很长一段时间 - 但到目前为止没有采取任何行动:

https://bugs.python.org/issue14074

argparse 允许 nargs>1 用于位置参数,但不允许 metavar 成为元组

【讨论】:

  • 谢谢。我的原始代码已经有两个位置参数,我的发现是由于重构(我希望我的位置参数像可选参数一样处理)。我想我会坚持下去。
【解决方案2】:

hpaulj's answer 之后,这是使用action='append' 的另一种解决方法:

for name in 'width', 'height':
    parser.add_argument('size', type=int, help=name, metavar=name[0], action='append')
args = parser.parse_args(['4', '3'])
print(args)
parser.print_help()

输出:

Namespace(size=[4, 3])
usage: test.py [-h] w h

positional arguments:
  w           width
  h           height

【讨论】:

  • 我已经使用argparse 很长时间了,我不知道a) 可以将“附加”与位置一起使用,b) 可以多次使用不同的位置名称给出相同的位置名称帮助/元变量。好建议!
猜你喜欢
  • 2023-04-09
  • 2015-07-25
  • 2016-07-19
  • 1970-01-01
  • 1970-01-01
  • 2021-09-16
  • 1970-01-01
  • 1970-01-01
  • 2017-04-15
相关资源
最近更新 更多