Search code examples
pythonargparse

How do I set a default value for flag in argparse if the flag is given alone


import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-c',
                    '--cookies',
                    nargs='?',
                    default=5,
                    type=int,
)

args = parser.parse_args()

if args.cookies:
    print('cookies flag is set: ' + args.cookies)
else:
    print('cookies flag not set: ' + str(args.cookies))

I want it to work so that if the user gives -c then we know they want cookies, but we don't know how many cookies they want so we give them 5 by default (-c == 5 :).

If the user types -c 25 then we know they want 25 cookies.

If the user does not give a -c flag then we know they do not want cookies and cookies flag should not be set.

The way it works as above is that -c == 5 only when -c is not set by the user. But we do not want to give them cookies if they do not ask for it!

If they ask for a specific amount of cookies (ex: -c 10), then the code above works fine.


I fixed this problem by using a short custom action that checks if the flag is set and if no value is passed in I give it the default value.

This seems a bit convoluted and there must be an easier way. I've searched the argparse docs (looked at nargs, default, and const) but couldn't figure out a solution.

Any ideas? Thank you for your time.


Solution

  • You're looking for the const parameter, which the docs don't do a very good job of explaining.

    default always sets the value, even if the flag is not provided, unless it is overridden by a user input.

    const only sets the value if the flag is provided and no overriding value is provided.

    The nargs section has an example of how to use the const parameter:

    >>> parser = argparse.ArgumentParser()
    >>> parser.add_argument('--foo', nargs='?', const='c', default='d')
    >>> parser.add_argument('bar', nargs='?', default='d')
    >>> parser.parse_args(['XX', '--foo', 'YY'])
    Namespace(bar='XX', foo='YY')
    >>> parser.parse_args(['XX', '--foo'])
    Namespace(bar='XX', foo='c')
    

    Although the default keyword isn't necessary in your case, since you want the value to be None if the user does not provide the flag.