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 withprog=).
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 exitRemember
- 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.