26

I read the following in the argparse documentation:

'store_const' - This stores the value specified by the const keyword argument. (Note that the const keyword argument defaults to the rather unhelpful None.) The 'store_const' action is most commonly used with optional arguments that specify some sort of flag. For example:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='store_const', const=42)
>>> parser.parse_args('--foo'.split()) Namespace(foo=42)`

How is this different from setting a default value for the argument with the default option?

Amelio Vazquez-Reina
  • 91,494
  • 132
  • 359
  • 564

2 Answers2

38

Below describes the difference between default and store_const. Because of poor naming, this can indeed be very confusing.

There are basically two types of arguments Python supports:

Argument with value

Example: --seed 42

You cannot omit the value part even if you set default as shown below:

parser = argparse.ArgumentParser()
parser.add_argument('--seed', default=42)

parser.parse_args('--seed 20'.split()) # seed is now 20
parser.parse_args(''.split()) # seed is now 42

parser.parse_args('--seed'.split()) # ERROR, must supply argument value

Argument without value

Example: --no-cuda

Here you cannot supply value to the argument, either argument exist or it doesn't. The action = "store_const" means that the argument value is whatever is set in the const parameter when the argument is present. If argument is not present then it takes the value specified in the default parameter.

parser = argparse.ArgumentParser()
parser.add_argument('--use-cuda', action='store_const', const=False, default=True)

parser.parse_args('--use-cuda'.split()) # use-cuda is now False
parser.parse_args(''.split()) # use-cuda is now True

parser.parse_args('--use-cuda True'.split()) # ERROR: unrecognized arguments: True

Using const without default

Now what if you did not specify default? Well, in that case, default just assumes the value of None as shown below:

parser = argparse.ArgumentParser()
parser.add_argument('--use-cuda', action='store_const', const=False)

parser.parse_args('--use-cuda'.split()) # use-cuda is now False
parser.parse_args(''.split()) # use-cuda is now None

parser.parse_args('--use-cuda True'.split()) # ERROR: unrecognized arguments: True

Shortcut for boolean arguments

Now you can see that the value of const and default are usually opposite for the boolean arguments. To make this convenient, Python has shortcut actions called store_true and store_false. The store_true is same as const=True and default=False. The store_false other way around.

Shital Shah
  • 63,284
  • 17
  • 238
  • 185
20

What did you get with parse_args(''.split())? I'd expect foo=None.

Now add a default='39' to your argument definition.

default is the value that the attribute gets when the argument is absent. const is the value it gets when given. Note also that const is allowed only when the action is store_const (and a few other special cases).

Note what happens when I define a store_true action:

In [30]: p.add_argument('--bar', action='store_true')
Out[30]: _StoreTrueAction(option_strings=['--bar'], dest='bar', nargs=0, 
    const=True, default=False, type=None, choices=None, help=None, metavar=None)

The Action object that it creates has a const=True attribute, and default=False attribute. It also has nargs=0. It is a store_const action with these special values.

[An 'advanced' user could experiment with add_argument('--foo', nargs='?', default='one', const='two')].

hpaulj
  • 221,503
  • 14
  • 230
  • 353