Your first parser

argparse · Essentials · 8 min

Any script that takes input from the command line needs this instead of hand-parsing sys.argv.

The raw command line is sys.argv, a list of strings. Parsing it by hand quickly gets messy. argparse does it declaratively in three steps:

  • create a parser: parser = argparse.ArgumentParser(description="..."),
  • declare arguments: parser.add_argument("filename"),
  • parse: args = parser.parse_args().

parse_args() reads sys.argv[1:] and returns a Namespace, a simple object whose attributes are named after your arguments: args.filename. You can also pass an explicit list, parser.parse_args(["data.csv"]), which is how you test parsers and how the examples in these lessons run.

For free you get:

  • -h / --help, which prints a usage line and a description of every argument, then exits,
  • error handling: a missing or unknown argument prints usage and an error message to stderr and exits with status 2,
  • the program name in messages, from sys.argv[0] (override with prog=).

Put the parser in a function and call it from a main() guarded by if __name__ == "__main__":. That keeps the script importable and testable.

Example

import argparse

parser = argparse.ArgumentParser(prog="count", description="Count lines in a file.")
parser.add_argument("filename", help="file to read")

args = parser.parse_args(["notes.txt"])   # normally: parser.parse_args()
print(args)                                # Namespace(filename='notes.txt')
print(args.filename)                       # notes.txt

parser.print_help()
# usage: count [-h] filename
#
# Count lines in a file.
#
# positional arguments:
#   filename    file to read
#
# options:
#   -h, --help  show this help message and exit

Remember

  • ArgumentParser + add_argument + parse_args is the whole basic workflow
  • parse_args() returns a Namespace with one attribute per argument
  • --help and usage errors (exit status 2) come for free

Watch out for

  • Calling parse_args() at import time in a module, so importing it in tests reads pytest's arguments.

Check yourself

  1. What does parse_args() do when a required positional argument is missing?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.python.org/3/howto/argparse.html