Search code examples
pythonargparse

How can I add a keyword argument with a default value when setting up argparse in Python?


I have a function that sets what arguments can be passed to a command line when calling on a function, using argparse:

def parse_arguments(args):
    parser = argparse.ArgumentParser(usage=argparse_usage())
    parser.add_argument('mic', type=str)
    parser.add_argument('date_range', type=str)
    parser.add_argument('sleep_time', type=int, nargs="?", default=1)
    parser.add_argument('force', type=bool, action='store_false')

Two things are not so clear to me:

  1. How can I make the last argument force a keyword argument that defaults to False? - is this possible?
  2. Does store_false achieve the second part of the above in setting the default value to False?

Solution

  • parser = argparse.ArgumentParser(usage=argparse_usage())
    parser.add_argument('mic', type=str)
    parser.add_argument('date_range', type=str)
    parser.add_argument('sleep_time', type=int, nargs="?", default=1)
    parser.add_argument('force', type=bool, action='store_false')
    

    Since you seem to be working toward a general argparse-function link it may be good to clarify some issues.

    While there are parallels between function positional and keyword arguments, and argparse positionals and optionals, it's best to learn the syntax and purpose of each separately. Don't use your understanding of one to try to understand the other. You could use either argparse argument to provide function values (of either type).

    The key similarity is that positionals are required, in a specified order, in both cases. keyword/optionals may in most/some cases be omitted.

    argparse parses a list of strings, sys.argv. The type function, takes one of the strings and converts it in some way, or raises an error. str is a default function that doesn't do anything. int is the standard python function that converts a string into an integer (if it can). Similarly for float.

    bool, while allowed, is not useful. Only bool('') returns False. bool('False') does not. There's nothing your users can type on the command line that produces a boolean False. While it's possible to write or import an function that will parse words like 'True,False,false,yes,no,si,...' there is nothing built into python/argparse that does it for you.

    An optional with action='store_true' is the normal way of providing a boolean value. It has to be an optional/flagged argument. Default is False; if used it stores True in the dest. 'store_false' is the logical opposite, but rarely used because it's hard to explain to your users.

    nargs='?' is best used only for the last positional argument. It's a 'greedy' value (in the re sense). Same for the other variable nargs, *+. '?' when used with a flagged argument can function as a 3 way 'switch', setting either a default, a const, or a user provided value.

    After parsing, it's a good idea to print the args namespace object, at least during debugging. That way you get a clear idea of what the parser has done. In that namespace you won't see any difference between the positionals and the optionals. All you will see are user provided values or the defaults.