19

I cannot figure out this behaviour of argparse from the documentation:

import argparse

parser.add_argument("--host", metavar="", dest="host", nargs=1, default="localhost", help="Name of host for database.  Default is 'localhost'.")
args = parser.parse_args()
print(args)

Here is the output with and without an argument for "--host":

>> python demo.py
Namespace(host='localhost')

>> python demo.py --host host
Namespace(host=['host'])

In particular: why does the argument to "--host" get stored in a list when it is specified but not when the default is used?

Schemer
  • 1,635
  • 4
  • 19
  • 39
  • 4
    Because you specified `nargs=1`. When `nargs` is present, because you can set `nargs` to `+` or a larger number, the results are stored in a `list`. But the default is given as a string. You can write `default=["localhost"]` and the default will be a list as well. – Xin Yin Aug 16 '14 at 20:56
  • Thanks. Totally missed that. – Schemer Aug 16 '14 at 22:32
  • the `default` is added to the namespace as is (apart from any conversion that the `type` might do). `nargs` and `action` don't, for the most part, affect it. – hpaulj Aug 16 '14 at 23:20

3 Answers3

32

Remove the "nargs" keyword argument. Once that argument is defined argparse assumes your argument is a list (nargs=1 meaning a list with 1 element)

Joohwan
  • 2,374
  • 1
  • 19
  • 30
2

As an alternative and handy module: Docopt can be used for parsing command line arguments. Docopt transform a commandline into a dictionnary by defining values inside doc.

c24b
  • 5,278
  • 6
  • 27
  • 35
1

The question title and the question body ask two different questions. This is potentially a sign of the confusion I shared with the OP.

The title: why is the default a string not a list? The body: why is the given value a list not a string?

The selected answer provides the solution to the question in the body. The answer to the question in the title is:

The entry default="localhost" sets default to "localhost", which is a sting. To set it as a list, you could use: default=["localhost"].

Dave
  • 312
  • 3
  • 11
  • 1
    It's a little unclear whether the OP is puzzled more by the value being a list (as you were), or the default not being a list. The final question could be interpreted either way. – hpaulj Jan 23 '21 at 00:39
  • Agreed - I've edited my answer to point out that confusion, rather than say it's misleading. – Dave Jan 29 '21 at 11:53