How to handle Command Line Arguments in Python?

When you are running python programs from the command line, you can pass various arguments to the program and your program can handle it.

Here is a quick snippet of code that I will be explaining later:

import sys
if __name__ == "__main__":
    print("You passed: ", sys.argv)

When you run this program from the command line, you will get this kind of results:

$ python cmdargs.py
 You passed:  ['cmdargs.py']

Notice that the sys.argv is an array of strings containing all arguments passed to the program. And the first value(at zeroth index) of this array is the name of the program itself. You can put all kinds of check on it.

$ python cmdargs.py 1 2 "CloudxLab Inc"
 You passed:  ['cmdargs.py', '1', '2', 'CloudxLab Inc']

Why name check?

Please note that we are checking if the __name__ is equal to __main__ in order to avoid this code being executed when this file is included as a module.

The following code also runs fine.

import sys
print("You passed: ", sys.argv)
$ python cmdargs.py
 You passed:  ['cmdargs.py']

In python, you can include one python program in another program by using import. This is where the problem occurs.

$ python
 Python 3.9.5 (default, May  4 2021, 03:36:27)
 [Clang 12.0.0 (clang-1200.0.32.29)] on darwin
 Type "help", "copyright", "credits" or "license" for more information.
import cmdargs
You passed:  ['']         

Notice that the moment we imported cmdargs, it ran our print statement. To avoid this code being executed during import, we put a check if the __name__ is equal to __main__.

What about return value?

In Unix, every program returns a value to the operating system. In python, this is usually done by passing a signal in exit() like this:

import sys
if __name__ == "__main__":
    print("You passed: ", sys.argv)
    exit(146)

You can check this by using `$?` special variable in shell.

$ python cmdargs.py 1 2
 You passed:  ['cmdargs.py', '1', '2']
 (venv) MacBook-Air:codefun sandeep$ echo $?
 146

Notice that 146 being print by echo $? As a matter of convention, in case of success, our program should return 0 and in case of failure, it should return a non-zero value.

Parsing the command line

There is a very interesting module in Python which helps in parsing command line arguments called argparse

You can utilize it to make your application handle really complex arguments. Here is a small snippet of code from a file create_screen_shots.py where I used argparse recently to do complex processing of arguments.

import argparse
if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Export notes from google slides. The files will be created per slide. The name will n.txt where n starts from 0.')
    parser.add_argument('slidesid', metavar='SlideId', type=str, help='The id of the Google Slide.')
    parser.add_argument('dir', metavar='Directory', type=str, help='The directory in which these screenshots will be saved.', nargs='?')
    parser.add_argument('total_slides', metavar='total_slides', type=int, help='Total Number of slides', nargs='?')
  
    args = parser.parse_args()
    # Do something with it
    print(args.slidesid, args.dir, args.total_slides )

As added bonus, it also provides a nice help manual to the user of my program.

$ python create_screen_shots.py --help
 usage: create_screen_shots.py [-h] SlideId [Directory] [total_slides]
 Export notes from google slides. The files will be created per slide. The name will n.txt where n starts from 0.
 positional arguments:
   SlideId       The id of the Google Slide.
   Directory     The directory in which these screenshots will be saved.
   total_slides  Total Number of slides
 optional arguments:
   -h, --help    show this help message and exit

You can find out more about it in Python Doc of argparse.

Happy Learning!

You can experiment with and learn command-line arguments and various technologies using CloudxLab without installing anything on your computer.