Python argparse

How I use argparse.

Basic main() stub

import argparse
import sys

_examples = '''examples:

  # Run x, y, z
  python %(prog)s --output=tmp
'''

def main():
    parser = argparse.ArgumentParser(
        description='Argparse test',
        epilog=_examples,
        formatter_class=argparse.RawDescriptionHelpFormatter
    )
    parser.add_argument('--output', help='Specify output dir')
    args = parser.parse_args()
    print (vars(args))

if __name__ == "__main__":
    main()

Argument default values

Use default= to set a default value for an argument.

parser.add_argument('--format', default='html', help='Specify output format', metavar='FMT')

To show default values in your help strings, use %(default)s interpolation:

parser.add_argument('--format', default='html', help='Specify output format (default: %(default)s)')

If the default value is type str, it will be run through your type callback, otherwise it’s returned directly. This can be helpful when authoring help strings containing %(default)s:

parser.add_argument('--enable-x', type=_str_to_bool, default=True,
    help='Enable feature x (default: %(default)s)')
# outputs: --enable-x ENABLE_X   Enable feature x (default: True)
parser.add_argument('--enable-y', type=_str_to_bool, default='y',
    help='Enable feature y (default: %(default)s)')
# outputs: --enable-y ENABLE_Y   Enable feature y (default: y)

Argument types

Use type= to set your own type conversion function. A type is just a function that converts a string to some output type.

Numbers.

parser.add_argument('--int-val', type=int, help='Specify integer', metavar='N')
parser.add_argument('--flt-val', type=float, help='Specify float', metavar='N')

Booleans. You can’t use type=bool for booleans (try running bool('True') in the REPL if you want to know why.) Do this instead:

def _str_to_bool(v):
    if isinstance(v, bool):
        return v
    if v.lower() in ('yes', 'true', 't', 'y', '1'):
        return True
    elif v.lower() in ('no', 'false', 'f', 'n', '0'):
        return False
    else:
        raise argparse.ArgumentTypeError('Boolean value expected.')

parser.add_argument('--enable-output', type=_str_to_bool, default=False, metavar='BOOL')

Comma-separated list of values. How to specify a list of strings like python foo.py --tags=apple,fruit:

def _parse_comma_sep(s):
    if (s is None) or (s == ''):
        return []
    return s.split(',')

parser.add_argument('--tags', type=_parse_comma_sep, default='', metavar='TAGS')

Subcommands

Add a subcommand called log:

import argparse
import sys

_examples = '''examples:

  # Show log in html format
  python %(prog)s log --format=html
'''

def main():
    parser = argparse.ArgumentParser(
        description='Argparse test',
        epilog=_examples,
        formatter_class=argparse.RawDescriptionHelpFormatter
    )

    subparsers = parser.add_subparsers(help='Sub-commands', dest='command')
    parser_log = subparsers.add_parser('log', help='Show log')
    parser_log.add_argument('--format', help='Specify format', choices=['raw', 'html'])

    args = parser.parse_args()
    print (vars(args))

if __name__ == "__main__":
    main()