Command Line Arguments in Python

Overview

Computer programs are written with a specific purpose in mind. Tools on UNIX/Linux systems follow the idea of specialization - one tool for one task, but to do it as perfect as possible, then. Nethertheless, as with other tools, this allows you to combine single programs, and to create powerful tool chains.

With the help of command line arguments that are passed to programs, you can deal with much more specific use cases. Command line arguments allow you to enable programs to act in a certain way, for example to output additional information, or to read data from a specified source, and to interpret this data in a desired format.

In general, operating systems accept arguments in a certain notation, for example:

  • UNIX: "-" followed by a letter, like "-h"
  • GNU: "--" followed by a word, like "--help"
  • Microsoft Windows: "/" followed by either a letter, or word, like "/help"

These different approaches exist due to historical reasons. Many programs on UNIX-like systems support either the UNIX way, or the GNU way, or both. The UNIX notation is mostly used with single letter options while GNU presents a more readable options list particularly useful to document what is running.

Keep in mind that both the name and the meaning of an argument are specific to a program - there is no general definition, but a few conventions like --help for further information on the usage of the tool. As the developer of a Python script you decide which arguments are valid, and what they stand for, actually. This requires proper evaluation. Read on how to do it using Python.

Handling command line arguments with Python

Python 3 supports four different ways of handling command line arguments. The oldest one is the sys module. In terms of names, and its usage, it relates directly to the C library (libc). The second way is the getopt module which handles both short, and long options, including the evaluation of the parameter values.

Furthermore, two lesser-known ways exist. This is the argparse module which is derived from the optparse module available up to Python 2.7, formerly, and the docopt module is available from GitHub. All the modules are fully documented and worth reading.

The sys Module

This is a basic module that was shipped with the Python distribution from the early days on. It has a quite similar approach as the C library using argc/argv to access the arguments. The sys module implements the command line arguments in a simple list structure named sys.argv.

Each list element represents a single argument. The first one -- sys.argv[0] -- is the name of the Python script. The other list elements -- sys.argv[1] to sys.argv[n] -- are the command line arguments 2 to n. As a delimiter between the arguments, a space is in use. Argument values that contain a space in it have to be quoted, accordingly.

The equivalent of argc is just the number of elements in the list. To obtain this value use the Python len() operator. Example 2 will explain this in detail.

Example 1

In this first example, we determine the way we were called. This information is kept in the first command line argument, indexed with 0. Listing 1 displays how you obtain the name of your Python script.

Example 1: Determine the name of the Python script

import sys

print ("the script has the name %s" % (sys.argv[0])  

Save this code in a file named arguments-programname.py, and then call it as shown in Listing 1. The output is as follows and contains the file name, including its full path.

Listing 1: Call the script

$ python arguments-programname.py
the script has the name arguments-programname.py  
$
$ python /home/user/arguments-programname.py
the script has the name /home/user/arguments-programname.py  
Example 2

In the second example we simply count the number of command line arguments using the built-in len() method. sys.argv is the list that we have to examine. In Example 2, a value of 1 is subtracted to get the right index (argument list counters start from zero). As you may remember from Example 1, the first element contains the name of the Python script, which we skip here.

Example 2: Count the arguments

import sys

# count the arguments
arguments = len(sys.argv) - 1  
print ("the script is called with %i arguments" % (arguments))  

Save and name this file arguments-count.py. The call is displayed in Listing 2. This includes three different scenarios: a) a call without any further command line arguments, b) a call with two arguments, and c) with two arguments where the second one is a quoted string (a string that contains a space).

Listing 2: Call the script

$ python arguments-count.py
the script is called with 0 arguments  
$
$ python arguments-count.py --help me
the script is called with 2 arguments  
$
$ python arguments-count.py --option "long string"
the script is called with 2 arguments  
Example 3

The third example outputs every single argument the Python script that is called with, except the program name itself. Therefore, we loop through the command line arguments starting with the second list element. As stated before, this element has index 1.

Example 3: Output arguments

import sys

# count the arguments
arguments = len(sys.argv) - 1

# output argument-wise
position = 1  
while (arguments >= position):  
    print ("parameter %i: %s" % (position, sys.argv[position]))
    position = position + 1

In Listing 3 the Python script is named arguments-output.py. As done in Listing 2, the output illustrates three different calls: a) without any arguments, b) with two arguments, and c) also with two arguments where the second argument is a quoted string that consists of two single words, separated by a space.

Listing 3: call the script

$ python arguments-output.py
$
$ python arguments-output.py --help me
parameter 1: --help  
parameter 2: me  
$
$ python arguments-output.py --option "long string"
parameter 1: --option  
parameter 2: long string  
$

The getopt Module

As you may have seen before the sys module splits the command line string into single fascets only. The Python getopt module goes a bit further, and extends the separation of the input string by parameter validation. Based on the getopt C function, it allows both short, and long options including a value assignment.

In practice it requires the sys module to process input data properly. To do so, both the sys module and the getopt module have to be loaded beforehand. Next, from the list of input parameters we remove the first list element (see Example 4.1), and store the remaining list of command line arguments in the variable called argumentList.

Example 4.1: Preparing the input parameters

# include standard modules
import getopt, sys

# read commandline arguments, first
fullCmdArguments = sys.argv

# - further arguments
argumentList = fullCmdArguments[1:]

print argumentList  

Now, argumentList can be parsed using the getopts() method. Before doing that, getopts() needs to know about the valid parameters. They are defined like this:

Example 4.2: Preparing the valid parameters

unixOptions = "ho:v"  
gnuOptions = ["help", "output=", "verbose"]  

This means that these arguments are seen as the valid ones, now:

------------------------------------------
long argument   short argument  with value  
------------------------------------------
--help           -h              no
--output         -o              yes
--verbose        -v              no
------------------------------------------

Next, this allows you to process the argument list. The getopt() method requires three parameters - the list of the remaining arguments, as well as both the valid UNIX, and GNU options (see table above).

The method call itself is kept in a try-catch-statement to cover errors during the evaluation. An exception is raised if an argument is discovered that is not part of the list as defined before (see Example 4.2). The Python script will print the error message to the screen, and exit with error code 2.

Example 4.3: Parsing the argument list

try:  
    arguments, values = getopt.getopt(argumentList, unixOptions, gnuOptions)
except getopt.error as err:  
    # output error, and return with an error code
    print (str(err))
    sys.exit(2)

Finally, the arguments with the corresponding values are stored in the two variables named arguments, and values. Now, you can evaluate these variables (see Example 4.4). The for-loop goes through the list of recognized arguments, one entry after the next.

Example 4.4: Specific actions according to the argument

# evaluate given options
for currentArgument, currentValue in arguments:  
    if currentArgument in ("-v", "--verbose"):
        print ("enabling verbose mode")
    elif currentArgument in ("-h", "--help"):
        print ("displaying help")
    elif currentArgument in ("-o", "--output"):
        print (("enabling special output mode (%s)") % (currentValue))

In Listing 4 you see the output of the program calls. These calls are displayed with both valid and invalid program arguments.

Listing 4: Testing the getopts() method

$ python arguments-getopt.py -h
displaying help  
$
$ python arguments-getopt.py --help
displaying help  
$
$ python arguments-getopt.py --output=green --help -v
enabling special output mode (green)  
displaying help  
enabling verbose mode  
$
$ python arguments-getopt.py -verbose
option -e not recognized  
$

The argparse Module

The argparse module is available starting in Python 3.2, and an enhancement of the optparse module that exists up to Python 2.7. The Python documentation contains an API description and a tutorial that covers all the methods in detail.

It offers a command line interface with a standardized output, whereas the former two solutions leave most of the work in your hands. argparse allows the verification of fixed and optional arguments with name checking as either UNIX or GNU style. As a default optional argument, it includes -h, along with its long version --help. This argument is accompanied by a default help message describing the argument.

Example 5 shows the parser initialization, and Listing 5 shows the basic call, followed by the help message. In contrast to the Python calls we used in the previous examples, keep in mind to use Python 3 with these examples.

Example 5: Basic usage of the argparse module

# include standard modules
import argparse

# initiate the parser
parser = argparse.ArgumentParser()  
parser.parse_args()  

Listing 5: Calling the basic argparse program

$ python3 arguments-argparse-basic.py 
$
$ python3 arguments-argparse-basic.py -h
usage: arguments-argparse-basic.py [-h]

optional arguments:  
  -h, --help  show this help message and exit
$
$ python3 arguments-argparse-basic.py --verbose
usage: arguments-argparse-basic.py [-h]  
arguments-argparse-basic.py: error: unrecognized arguments: --verbose  
$

As the next step, we will add a custom description to the help message. Initializing the parser allows an additional text. Example 6 stores the description in the text variable, which is explicitly given to the argparse class. In Listing 6 you see what the output looks like.

Example 6: Adding a description to the help message

# include standard modules
import argparse

# define the program description
text = 'This is a test program. It demonstrates how to use the argparse module with a program description.'

# initiate the parser with a description
parser = argparse.ArgumentParser(description = text)  
parser.parse_args()  

Listing 6: Calling the help with a program description

$ python3 arguments-argparse-description.py --help
usage: arguments-argparse-description.py [-h]

This is a test program. It demonstrates how to use the argparse module with a  
program description.

optional arguments:  
  -h, --help  show this help message and exit

As the final step we will add an optional argument named -V (UNIX style), which has a corresponding GNU style argument named --version. To do so we use the method add_argument() that we call with three parameters (displayed for --version, only):

  • the name of the parameter: --version
  • the help text for the parameter: help="show program version"
  • action (without additional value): action="store_true"

The source code for that is displayed in Example 7. Reading the arguments into the variable called args is done via the parse_args() method from the parser object. Note that you submit both the short and the long version in one call. Finally, you check if the attributes args.V or args.version are set and output the version message.

Example 7: Defining an optional argument

# include standard modules
import argparse

# initiate the parser
parser = argparse.ArgumentParser()  
parser.add_argument("-V", "--version", help="show program version", action="store_true")

# read arguments from the command line
args = parser.parse_args()

# check for --version or -V
if args.version:  
    print("this is myprogram version 0.1")

Listing 7 displays the output if you call the program._

$ python3 arguments-argparse-optional.py -V
this is myprogram version 0.1  
$
$ python3 arguments-argparse-optional.py --version
this is myprogram version 0.1  

The --version argument does not require a value to be given on the command line. That's why we set the action argument to "store_true". In other cases you need an additional value, for example if you specify a certain volume, height, or width. This is shown in the next example. As a default case, please note that all the arguments are interpreted as strings.

Example 8: Defining an optional argument with value

# include standard modules
import argparse

# initiate the parser
parser = argparse.ArgumentParser()

# add long and short argument
parser.add_argument("--width", "-w", help="set output width")

# read arguments from the command line
args = parser.parse_args()

# check for --width
if args.width:  
    print("set output width to %s" % args.width)

Listing 8 shows different output values. This includes both the short and the long version as well as the help message.

Listing 8: Different output values

$ python3 arguments-argparse-optional2.py -w 10
set output width to 10  
$
$ python3 arguments-argparse-optional2.py --width 10
set output width to 10  
$
$ python3 arguments-argparse-optional2.py -h
usage: arguments-argparse-optional2.py [-h] [--width WIDTH]

optional arguments:  
  -h, --help            show this help message and exit
  --width WIDTH, -w WIDTH
                        set output width

Conclusion

In this article we showed many different methods of retrieving command line arguments in Python, including using sys, getopt, and argparse. These modules vary in functionality -- some providing much more than others. sys is fully flexible whereas both getoptand argparse require some structure. In contrast, they cover most of the complex work that sys leaves to your hands. After working through the examples provided, you should be able to determine which module suits your project best.

In this article we did not talk about the docopts module -- we just mentioned it. This module follows a totally different approach, and will be explained in detail in one of the next articles.

References

Acknowledgements

The author would like to thank Gerold Rupprecht for his support, and critics while preparing this article.

Author image
Berlin -- Genève -- Cape Town Twitter Github
IT developer, trainer, and author. Coauthor of the Debian Package Management Book (http://www.dpmb.org/).