In command-line programs, it is often necessary to retrieve command-line arguments. Python’s built-in sys.argv stores the complete list of arguments, from which we can parse the required parameters:
# copy.py
import sys
print(sys.argv)
source = sys.argv[1]
target = sys.argv[2]
# TODO...
Run the above copy.py and pass arguments—the output will be as follows:
['copy.py', 'source.txt', 'copy.txt']
This method works for simple arguments, but parsing becomes extremely cumbersome with slightly complex parameters (e.g., using -d to copy directories, or --filename *.py to filter filenames).
To simplify argument parsing, we can use the built-in argparse library: after defining the type of each argument, it directly returns valid parsed parameters.
Suppose we want to write a command-line program to back up a MySQL database, which requires the following input parameters:
host: MySQL hostname or IP (defaults to localhost if not provided);port: MySQL port number (integer type, defaults to 3306 if not provided);user: Username for logging into MySQL (required);password: Password for logging into MySQL (required);gz: Whether to compress the backup file (defaults to False if not provided);outfile: Path to save the backup file (required).Here, outfile is a positional argument, while the others are “keyword arguments” (e.g., --user root).
A complete example of parsing arguments with argparse is shown below:
# backup.py
import argparse
def main():
# Define an ArgumentParser instance:
parser = argparse.ArgumentParser(
prog='backup', # Program name
description='Backup MySQL database.', # Description
epilog='Copyright(r), 2023' # Epilogue/Additional info
)
# Define positional argument:
parser.add_argument('outfile')
# Define keyword arguments:
parser.add_argument('--host', default='localhost')
# This argument must be an integer:
parser.add_argument('--port', default='3306', type=int)
# Allow short alias -u for --user:
parser.add_argument('-u', '--user', required=True)
parser.add_argument('-p', '--password', required=True)
parser.add_argument('--database', required=True)
# The gz argument takes no value; use action='store_true'
# (presence of -gz means True):
parser.add_argument('-gz', '--gzcompress', action='store_true',
required=False, help='Compress backup files by gz.')
# Parse arguments:
args = parser.parse_args()
# Print parsed arguments:
print('parsed args:')
print(f'outfile = {args.outfile}')
print(f'host = {args.host}')
print(f'port = {args.port}')
print(f'user = {args.user}')
print(f'password = {args.password}')
print(f'database = {args.database}')
print(f'gzcompress = {args.gzcompress}')
if __name__ == '__main__':
main()
When valid arguments are provided, the program parses all required parameters:
$ ./backup.py -u root -p hello --database testdb backup.sql
parsed args:
outfile = backup.sql
host = localhost
port = 3306
user = root
password = hello
database = testdb
gzcompress = False
If required arguments are missing or invalid, detailed error messages are reported:
$ ./backup.py --database testdb backup.sql
usage: backup [-h] [--host HOST] [--port PORT] -u USER -p PASSWORD --database DATABASE outfile
backup: error: the following arguments are required: -u/--user, -p/--password
Even more conveniently, entering -h prints the help message:
$ ./backup.py -h
usage: backup [-h] [--host HOST] [--port PORT] -u USER -p PASSWORD --database DATABASE outfile
Backup MySQL database.
positional arguments:
outfile
optional arguments:
-h, --help show this help message and exit
--host HOST
--port PORT
-u USER, --user USER
-p PASSWORD, --password PASSWORD
--database DATABASE
-gz, --gzcompress Compress backup files by gz.
Copyright(r), 2023
The core code to retrieve valid arguments is this single line:
args = parser.parse_args()
There is no need to catch exceptions manually—parse_args() handles this conveniently:
-h is provided: it prints the help message and exits the process;Namespace object, and you can access parsed arguments as attributes (e.g., args.outfile), making usage extremely straightforward.Clearly, using argparse greatly simplifies argument parsing. We can focus on defining arguments and directly retrieve valid input parameters.
With argparse, parsing command-line arguments only requires defining argument types to get valid input parameters—this drastically simplifies the work of retrieving command-line arguments.