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
andinput_file
are required arguments. Theindent
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 is the argparse module used for in Python?
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?
How do you add a positional argument using argparse?
How do you add an optional argument with a short and long form using argparse?
What does the ‘action’ parameter do in argparse?
How can you specify a default value for an argument in argparse?
What does the ‘metavar’ parameter do in argparse?