Python - Circumvent argparse nargs错误

时间:2017-03-27 10:39:59

标签: python argparse

我有一个这样的程序:

prog.py filename -r

使用我提供的默认默认值

prog.py filename -r 0 500 20

使用0, 500 and 20

我已成功实现此目的:

class RdistAction(argparse.Action):
    def __call__(self,parser,namespace,values,option_string=None):
        if not values:
            setattr(namespace,self.dest,[0, 1000, 50])
        else:
            setattr(namespace,self.dest,values)

parser = argparse.ArgumentParser()
parser.add_argument("-r", "--rdist", action=RdistAction, nargs='*', type=int)
args = parser.parse_args()

但是我想要固执,因为我最初的目标是将nargs设置为3.但是当我在上面的代码中使用nargs = 3时,我收到一条错误消息,指出预期有3个参数。

我已经用Google搜索了,结果我的肠道告诉我,我必须添加def __init__并修改该功能中的内容。我可以在nargs='*'时获得与上述代码相同的结果,但使用nargs=3代替吗?

2 个答案:

答案 0 :(得分:13)

如果我将add_argument行更改为nargs='3',我认为我会收到你正在接受的错误:

Traceback (most recent call last):
  File "python", line 12, in <module>
ValueError: length of metavar tuple does not match nargs

如果我设置nargs=3(不带引号),那么它适用于我:

import argparse

class RdistAction(argparse.Action):
    def __call__(self,parser,namespace,values,option_string=None):
      if not values:
        setattr(namespace,self.dest,[0, 1000, 50])
      else:
        setattr(namespace,self.dest,values)

parser = argparse.ArgumentParser()
parser.add_argument("-r", "--rdist", action=RdistAction, nargs=3, type=int)
print parser.parse_args('-r 0 500 20'.split())

给出

Namespace(rdist=[0, 500, 20])

这就是你要找的东西吗?

这里的诀窍是,如果nargs不是其中一个特殊字符(&#39;?&#39;,&#39; *&#39;,&#39; +&#39; ,等等,然后它需要是一个整数,而不是一个字符串。

请注意,the documentation确实指出了这一点。

答案 1 :(得分:0)

正如我在上一个问题中指出的那样,只需省略final Document document = builder.parse(data.toXMLString());就可以将-r放在args命名空间中。你不需要做任何特别的事情。

default有第三个选项nargs='?'

您的自定义操作有点像这样,因为它在使用const时没有任何字符串时为命名空间分配自定义值。

解析大致如下:

  • 将默认值分配给命名空间
  • 循环输入,按顺序处理位置和选项
  • 对于每个参数,请调用其-r
  • 传递的Action.__call__数量取决于values参数

您的自定义nargs无法控制RdistAction的数量,除非通过其values属性。 nargs正好表示3,nargs=3表示'尽可能多的给你'(即0或结尾或下一个标志)。

nargs='*'中,一个Action会提供所有剩余的optparse字符串,并且可以根据需要使用它们。但是在argv中,分配是在更高级别完成的,并且Action使用它给出的内容。

我已经在Python错误/问题扩展argparse中探讨了包括nargs类似范围,例如regex。但这需要更改解析器的核心。

您仍然没有解释为什么需要这个[0,3]选项。