Python argparse与nargs行为不正确

时间:2013-10-07 15:17:34

标签: python python-2.7 argparse

这是我的argparse示例说sample.py

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-p", nargs="+", help="Stuff")
args = parser.parse_args()
print args

Python - 2.7.3

我希望用户提供-p选项后用空格分隔的参数列表。例如,如果您运行

$ sample.py -p x y 
Namespace(p=['x', 'y'])

但我的问题是,当你运行

$ sample.py -p x -p y
Namespace(p=['y'])

既不在这里,也不在那里。我想要以下其中一个

  • 向用户抛出异常,要求他不要使用-p两次而只是将它们作为一个参数提供
  • 假设它是相同的选项并生成['x','y']列表。

我可以看到python 2.7正在做的两件事让我感到困惑。我可以让python执行上面记录的两种行为之一吗?

2 个答案:

答案 0 :(得分:2)

要生成['x','y']列表,请使用action='append'。实际上它给出了

Namespace(p=[['x'], ['y']])

对于每个-p,它会根据['x']提供列表nargs='+',但append表示将该值添加到命名空间已有的值。默认操作只是设置值,例如NS['p']=['x']。我建议您查看文档中的action段。

optionals允许按设计重复使用。它可以启用appendcount等操作。通常用户不希望重复使用它们,或者对最后一个值感到满意。 positionals(不包含-flag)不能重复(nargs允许的除外)。

How to add optional or once arguments?对如何创建“无重复”参数有一些建议。一种是创建自定义action类。

答案 1 :(得分:0)

我遇到了同样的问题。我决定按照mgilson的建议采用自定义行动路线。

import argparse
class ExtendAction(argparse.Action):
  def __call__(self, parser, namespace, values, option_string=None):
    if getattr(namespace, self.dest, None) is None:
      setattr(namespace, self.dest, [])
    getattr(namespace, self.dest).extend(values)
parser = argparse.ArgumentParser()
parser.add_argument("-p", nargs="+", help="Stuff", action=ExtendAction)
args = parser.parse_args()
print args

这导致

$ ./sample.py -p x -p y -p z w
Namespace(p=['x', 'y', 'z', 'w'])

但是,如果默认情况下库中有action='extend'选项,那么它会更加简洁。