Python Command Line Arguments

Python makes scripting common tasks simple and fast. Taking advantage of command line arguments can save you the trouble of loading your favorite IDE.
python command line arguments alpharithms

Python supports the use of command line arguments providing developers an easy entry point for accepting program arguments. Complex Python programs or simple scripts can be run, with arguments, directly from the terminal.

Python provides support for command line usage via the sys, argparse, getopt and other modules from the standard library. These modules make short work of parsing and checking command line arguments as well as adding options, flags, and even handling basic logical functions. Before we dive in, let’s consider where the Python command line came from.

The Command Line Interface (CLI)

Command line interfaces (CLI) have been a common means of providing input to computer programs since the advent of the computer terminal. As early as the 1950’s computers began using terminals to interface with users in real-time, such as Jay Forrester’s Whirlwind computer1. Modern CLI applications are often run via a Shell2. As described by the developer of the original Unix Shell – Ken Thompson3:

The Shell is a command line interpreter: it reads lines typed by the user and interprets them as requests to execute other programs. In simplest form, a command line consists of the command name followed by arguments to the command, all separated by spaces

We’ll not dive any further into the history — but halt and focus on part of Thompson’s description: the command name followed by arguments to the command. This is the essence of command line arguments and how, even today, a Python script accepting command line arguments is executed. Now we know the format, let’s consider how Python interprets our command and arguments.

ArgC & ArgV

Python’s command line arguments are accessible via the sys module. This format is modeled after the C-Language’s use of the parameters argc and argv. These represent the following values:

  • argc (argument count) – The number of arguments passed to a program.
  • argv (argument vector) – A list of arguments passed to the program.

According to the latest ISO C-language standards, agrc and argv can be further contextualized by considering a function named main4:

The function called at program startup is named main …  with two parameters (referred to here as argc and argv, though any names may be used, as they are local to the function in which they are declared)

C convention states the primary function is called main — another C-language feature adopted by Python. Python defines what is known as a “top-level code environment” in which the first user-specified module starts to run—i.e. the code that would accept command line arguments.

In keeping with C-language conventions, this main program (receiving the __name__ attribute of __main__ in Python) provides access to any command line arguments via the argc and argv methods provided in the sys module. Enough with the history and technical details — let us now look at how to handle command line arguments in Python.

The sys Module, argc, & argv

Python’s sys module “provides access to some variables used or maintained by the interpreter.”  This module provides a list of all command line arguments accessible as sys.argv. There is no sys.argc but the number of arguments can be measured by taking the length of argv – 1. Let’s see an example via running a fake program and taking 3 arguments.

$ python3 fake_func.py val1 val2 val3

The name of our program is fake_func.py and val1, val2, and val3 are the arguments being passed as command line arguments. The value of sys.argv in this case would be as follows:

argv: ['fake_func.py', 'val1', 'val2', 'val3']

Notice the first argument is the name of our program — meaning the total number of arguments is the length of the argv list – the name of the program. In Python: len(sys.argv) - 1. This will return the integer value 3 serving as a stand-in for argc.

Parsing Command Line Arguments

Python’s sys.argv works great at retrieving command line arguments but offers no support at handling them. For that, each program will have unique requirements. There are some common concerns that are relevant to any use of the sys.argv however:

  • Error Handling – Ensuring a program can handle the given number of arguments.
  • Type conversions – The sys.argv returns string values that may need to be cast to other types.
  • Flags & Options – Handling program-specific options or flags.

The first two points are relatively trivial and can be addressed via common Python syntax. The third gets a bit more complex but is relatively easy via the argparse module. Below is a brief discussion of each point of concern.

Error Handling

Error handling consists of two primary concerns: the minimum required number of arguments has been supplied and the program isn’t trying to access arguments that aren’t there — both are closely related. Consider the following command line execution of our program fake_prog.py again:

$ python3 fake_prog.py arg1 arg2

What if the program expects a third value arg3? Presumably, the program would have code to access that via syntax similar to the following: sys.argv[3]. In this case, argv would only have three values: ['fake_prog.py', 'arg1', 'arg2'] and length 3.

Attempting to access index 3 will cause an IndexError exception. This issue can be handled in one of two ways: an initial check for the correct count or individual checking for each argument. The first is more holistic, and can be implemented as follows:

import sys

# Checks for the correct number of arguments
if len(sys.argv) != 4:
    raise SystemExit("Usage: python3 fake_prog.py arg1 arg2 arg3")

This makes a call to SystemExit if the number of arguments is fewer than the three expected. Remember — we’re comparing to 4 because the name of the program (fake_prog.py) will always be the first argument. An alternative approach would use a try-except block for an IndexError for each access. We’ll skip that code since it’s cumbersome and stinks.

Type Conversions

Values found in sys.argv are interpreted as string values — a characteristic common to most programming languages. That leaves the conversion to non-string values up to us developers. This will mostly be a case of parsing a value as a numerical type (float, int, etc.), a String, or a char.

Each program is likely to have custom requirements for each argument. However, a general approach is suitable for many cases by which the type of a value is checked. Let’s consider an example where every argument is expected to be an integer value:

import sys

# Tries to convert all arguments to an integer
for arg in sys.argv[1:]:
    try:
        parsed = int(arg)
    except ValueError:
        raise SystemExit("All arguments must be an integer!")

This program loops over all elements in the sys.argv list — other than the first argument which is the program name — and attempts to convert the string value to an integer. If this fails with a ValueError, the program will exist and display a usage message. This will cause the program to exit if any argument is not an integer value. A similar approach can be used to handle a wide range of requirements for parsing command line args.

Flags & Options

Handling options and flags via the command line is simple in Python — provided one uses the argparsegetopt, or optparse modules. Here we’ll cover a brief example of how to designate syntax for options, parse command-line arguments, and check for matches with options. For simplicity, we’ll focus only on using the argparse module.

Let’s extend the functionality of our fake_prog.py to optionally print out the sum of all the arguments (after confirming as integers.) This is done via argparse as follows:

import argparse

# creates a new argpare instance
parser = argparse.ArgumentParser(description="Add some integers")

# adds definition for a addition option
parser.add_argument("nums", type=int, nargs="+")
parser.add_argument("--sum", dest="accumulate", action="store_const", const=sum, default=max, help="sums a series of integer values")

# Parses the arguments
args = parser.parse_args()

# Prints the sum of each value
print("Total: ", args.accumulate(args.nums))


# Output
Total: 15

Here we see the argparse module used to not only define a –sum flag but to also parse the integer values and sum them. In this use case, argparse showcases itself as a platform via which developers can not just handle parsing command line arguments in Python but also as a means to inject logic.

Final Thoughts

Parsing command line arguments in Python can be simple or complex depending on how a program is designed. Basic argument collection can be implemented via the sys.argv approach in a way that mimics many C-based languages. We also saw how the argparse module can be used to parse any number of options — even implementing logic to handle the input.

Using command line arguments can help enable a Python program to be executed quickly and conveniently from the command line. This is great for simple tasks like conditionally copying files from one directory to another without mucking about with shell scripts or launching long-running, complex pipelines. Either way, Python makes implementing command line arguments relatively easy.

References

  1. J. W. Forrester and R. R. Everett, “The Whirlwind computer project,” in IEEE Transactions on Aerospace and Electronic Systems, vol. 26, no. 5, pp. 903-910, Sept. 1990, doi: 10.1109/7.102724.
  2. S. R. Bourne, “Unix time-sharing system: the unix shell,” in The Bell System Technical Journal, vol. 57, no. 6, pp. 1971-1990, July-Aug. 1978, doi: 10.1002/j.1538-7305.1978.tb02139.x.
  3. O. M. Ritchie and K. Thompson, “The UNIX time-sharing system,” in The Bell System Technical Journal, vol. 57, no. 6, pp. 1905-1929, July-Aug. 1978, doi: 10.1002/j.1538-7305.1978.tb02136.x.
  4. ISO/IEC. (2018). ISO International Standard ISO/IEC 9899:2018 – Programming Language C++. Geneva, Switzerland: International Organization for Standardization (ISO).
Zαck West
Full-Stack Software Engineer with 10+ years of experience. Expertise in developing distributed systems, implementing object-oriented models with a focus on semantic clarity, driving development with TDD, enhancing interfaces through thoughtful visual design, and developing deep learning agents.