Argparse in Python

The argparse module in Python is a powerful tool for handling command-line arguments in scripts. It allows developers to define both positional and optional arguments, specify their types, and provide help messages. The module can automatically generate usage messages and handle errors related to argument parsing, making it an essential tool for creating user-friendly command-line interfaces.

Overview

To use the argparse module, you create an instance of ArgumentParser, populate it with arguments, and then read both the optional and positional arguments. This process is illustrated in the following example:

Example: Basic Argument Parsing

from argparse import ArgumentParser
 
def main():
    parser = ArgumentParser()
    parser.add_argument("indent", type=int, help="indent for report")
    parser.add_argument("input_file", help="read data from this file")   #A
    parser.add_argument("-f", "--file", dest="filename",             #B
                  help="write report to FILE", metavar="FILE")
    parser.add_argument("-x", "--xray", 
                  help="specify xray strength factor")
    parser.add_argument("-q", "--quiet",
                  action="store_false", dest="verbose", default=True, #C
                  help="don't print status messages to stdout")
 
    args = parser.parse_args()
 
    print("arguments:", args)
if __name__ == "__main__":
    main()

In this example, an ArgumentParser instance is created, and several arguments are added:

  • Positional Arguments: indent and input_file are required arguments. The indent argument must be an integer.
  • Optional Arguments:
    • -f or --file specifies a file name to write the report to.
    • -x or --xray allows specifying an x-ray strength factor.
    • -q or --quiet is a flag that, when set, suppresses status messages.

Advanced Usage

The argparse module also supports more advanced features, such as handling file inputs directly and supporting multiple file arguments.

Example: File Handling with argparse

#!/usr/bin/env python3
# [File: word_count_program.py](https://livebook.manning.com/book/the-quick-python-book-fourth-edition/chapter-11/59)
""" Reads a file and returns the number of lines, words,
    and characters - similar to the UNIX wc utility
"""
import sys
import argparse
 
def main():
    # initialize counts
    line_count = 0
    word_count = 0
    char_count = 0
    byte_count = 0 
    longest_line = 0
 
    parser = argparse.ArgumentParser(usage=__doc__)
    parser.add_argument("-c", "--chars",
                  action="store_true", dest="chars", default=False,
                  help="display number of characters")
    parser.add_argument("-w", "--words",
                  action="store_true", dest="words", default=False,
                  help="display number of words")
    parser.add_argument("-l", "--lines",
                  action="store_true", dest="lines", default=False,
                  help="display number of lines")
    parser.add_argument("-L", "--longest",
                  action="store_true", dest="longest", default=False,
                  help="display longest line length")
    parser.add_argument("file", nargs='?', type=argparse.FileType('r'), #A
                        default=sys.stdin,   #B
                        help="read data from this file")   
    args = parser.parse_args()
    
    with  args.file  as infile:
        for line in infile.readlines():   #C
            line_count += 1
            char_count += len(line)
            words = line.split()
            word_count += len(words)
            if len(line) > longest_line:
                longest_line = len(line)
 
    default_args = any([getattr(args, _) for _ in ('chars', 'words', 'lines', 'longest')])
 
    if not default_args:
        args.chars = args.lines = args.words = True
 
    if args.lines:
        print(f"{line_count:3}", end=" ")
    if args.words:
        print(f"{word_count:4}", end=" ")
    if args.chars:
        print(f"{char_count:4}", end=" ")
    if args.longest:
        print(f'{longest_line}', end=" ")
    if args.file.name != '<stdin>':      #D
        print(f'{args.file.name}', end=" ")
    print()
 
if __name__ == '__main__':
    main()

In this example, the argparse.FileType('r') argument type is used to open a file automatically for reading. If no file is specified, the script defaults to reading from sys.stdin. This approach allows the script to handle both file inputs and standard input seamlessly.

Example: Handling Multiple Files

# [prompt: Refactor the cell above to make the script support input/output](https://livebook.manning.com/book/the-quick-python-book-fourth-edition/chapter-11/59)
# [        redirection. Output should be similar to that of wc utility.](https://livebook.manning.com/book/the-quick-python-book-fourth-edition/chapter-11/59)
 
import argparse
import sys
 
""" Reads a file and returns the number of lines, words,
    and characters - similar to the UNIX wc utility
"""
 
def main():
    parser = argparse.ArgumentParser(usage=__doc__)
    parser.add_argument("filename", nargs='*')   #A
    parser.add_argument("-l", "--lines", dest="lines",
                      action='store_true', default=False,
                      help="Show only line count")
    parser.add_argument("-w", "--words", dest="words",
                      action='store_true', default=False,
                      help="Show only word count")
    parser.add_argument("-c", "--chars", dest="chars",
                      action='store_true', default=False,
                      help="Show only character count")
    parser.add_argument("-L", "--longest", dest="longest",
                      action='store_true', default=False,
                      help="Show length of longest line")
    args = parser.parse_args()
 
    if not sys.stdin.isatty():    #B
        # Read from standard input
        lines = sys.stdin.readlines()
    else:
        for filename in args.filename:  #C
            with open(filename) as infile:
                lines = infile.readlines()
 
    line_count = len(lines)
    word_count = sum(len(line.split()) for line in lines)
    char_count = sum(len(line) for line in lines)
    longest_line_length = max(len(line) for line in lines)
 
    if args.lines:
        print(f"{line_count}")
    elif args.words:
        print(f"{word_count}")
    elif args.chars:
        print(f"{char_count}")
    elif args.longest:
        print(f"{longest_line_length}")
    else:
        print(f"{line_count} {word_count} {char_count}")
 
if __name__ == '__main__':
    main()

This version allows for multiple file name arguments by using the "*" option for the argument, which returns the file names as a list. The script processes each file in the list, making it more similar to the wc utility, which can handle multiple files.

FAQ (Frequently asked questions)

What types of arguments can argparse handle?

Can argparse specify argument types and provide help messages?

Does argparse automatically generate usage messages?

How does argparse handle errors related to argument parsing?

sitemap

Unable to load book!

The book could not be loaded.

(try again in a couple of minutes)

manning.com homepage
test yourself with a liveTest