The Python Oracle

argparse: Default value for nargs='*'?

--------------------------------------------------
Rise to the top 3% as a developer or hire one of them at Toptal: https://topt.al/25cXVn
--------------------------------------------------

Music by Eric Matyas
https://www.soundimage.org
Track title: Puzzle Game 2 Looping

--

Chapters
00:00 Argparse: Default Value For Nargs='*'?
00:41 Answer 1 Score 2
01:03 Accepted Answer Score 4
01:34 Answer 3 Score 2
01:50 Thank you

--

Full question
https://stackoverflow.com/questions/2170...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #argparse

#avk47



ACCEPTED ANSWER

Score 4


You could use a custom action:

import argparse
class EmptyIsTrue(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        if len(values) == 0:
            values = True
        setattr(namespace, self.dest, values)

parser = argparse.ArgumentParser()
parser.add_argument('-m', '--music', nargs='*', default=False, action=EmptyIsTrue)
print(parser.parse_args([]))
# Namespace(music=False)

print(parser.parse_args(['-m']))
# Namespace(music=True)

print(parser.parse_args('-m 1 2'.split()))
# Namespace(music=['1', '2'])

If you have only one argument to handle this way, then

arg.music = True if len(arg.music) == 0 else arg.music

is simpler. If you have many such arguments, then defining a custom action could reduce the repetition, and help ensure all those arguments are treated the same way.




ANSWER 2

Score 2


The following hack after the argparse section solves your problem:

import argparse

# Same as your code above
parser = argparse.ArgumentParser()
parser.add_argument('-m', '--music', nargs='*', default=False)
args = parser.parse_args()

# Modifies args.music: [] -> True
args.music = True if args.music==[] else args.music

print(args.music)

Tested in the command line, it gives:

$ python /tmp/blah.py -m
True

 $ python /tmp/blah.py -m 1 -m 2
['2']

$ python /tmp/blah.py -m 1 2 3
['1', '2', '3']

$ python /tmp/blah.py
False



ANSWER 3

Score 2


What about :

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-m', '--music', nargs='*', default=False)
args = parser.parse_args()

if vars(args).get('music', False) is not False:
    if not args.music:
        args.music = True
print args.music

Output:

tmp:/>python arg.py
False
tmp:/>python arg.py -m
True
tmp:/>python arg.py -m 1 2 3
['1', '2', '3'] 
tmp:/>