Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - Circumvent argparse nargs error

I have a program that works like this:

prog.py filename -r

Uses default default values given by me

prog.py filename -r 0 500 20

Uses 0, 500 and 20

I've managed to achieve this using:

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()

But I want to be stubborn, as my original goal was to have nargs set to 3. But when I use nargs=3 in the above code, I get an error message stating that 3 arguments were expected.

I've googled around, and from the results my gut tells me that I have to add def __init__ and modify something in that function. Is it possible to get the same results I get in the above code when nargs='*', but with nargs=3 instead?

like image 712
AltoBalto Avatar asked Mar 27 '17 10:03

AltoBalto


People also ask

What does Nargs mean Argparse?

Number of Arguments If you want your parameters to accept a list of items you can specify nargs=n for how many arguments to accept. Note, if you set nargs=1 , it will return as a list not a single value. import argparse parser = argparse. ArgumentParser() parser.

How do you get past the Argparse list?

To pass a list as a command-line argument with Python argparse, we can use the add_argument to add the argument. to call add_argument with the argument flag's short and long forms. We set nargs to '+' to let us take one or more argument for the flag.

What is Store_true in Python?

The store_true option automatically creates a default value of False. Likewise, store_false will default to True when the command-line argument is not present.

What is parser Add_argument in Python?

parser. add_argument('indir', type=str, help='Input dir for videos') created a positional argument. For positional arguments to a Python function, the order matters. The first value passed from the command line becomes the first positional argument. The second value passed becomes the second positional argument.


1 Answers

If I change your add_argument line to have nargs='3', I think I get the error you're taking about:

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

If I set nargs=3 (without the quotes), then it works for me:

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())

gives

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

Is that what you're looking for?

The trick here is that if nargs isn't one of the special characters ('?', '*', '+', etc), then it needs to be an integer, not a string.

Note that the documentation does point this out.

like image 199
Sam Mussmann Avatar answered Oct 23 '22 01:10

Sam Mussmann