Search code examples
pythonoptparse

python - beginner - integrating optparse in a program


I've started a serious attempt to learn some Python as my first programming language with some basic knowledge on algorithms. Since everyone recommends that the best way to start is to find something useful to do, I've decided to do a small script to manage my repositories.

Basic things: - Enable/Disable YUM repositories - Change priority on current YUM repositories - Add/Remove repositories

While parsing the file and replace/add/remove data is quite simple, I'm struggling (mainly with maybe lack of knowledge) with a single thing with 'optparse'... I want to add to an option (-l) which lists the current available repositories... I've made a simple function that does this job (not something very elaborate), but I'm unable to 'connect' it with the '-l' on optparse. Anyone could provide examples/suggestions on how to make this?

The current script is something like this:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import sys
import optparse
import ConfigParse

repo_file = "/home/nmarques/my_repos.repo"

parser = optparse.OptionParser()
parser.add_option("-e", dest="repository", help="Enable YUM repository")
parser.add_option("-d", dest="repository", help="Disable YUM repository")
parser.add_option("-l", dest="list", help="Display list of repositories", action="store_true")
(options, args) = parser.parse_args()

def list_my_repos()
    # check if repository file exists, read repositories, print and exit
    if os.path.exists(repo_file):
        config = ConfigParser.RawConfigParser()
        config.read(repo_file)
        print "Found the following YUM repositories on " + os.path.basename(repo_file) + ":"
        for i in config.sections():
            print i
        sys.exit(0)
    # otherwise exit with code 4
    else:
        print "Main repository configuration (" + repo_file +") file not found!"
        sys.exit(4)

list_my_repos()

Any suggestions to improve (docs, examples) are most welcome. The main goal once more, is that when I execute script.py -l it can run list_my_repos().


Solution

  • Parsing options using optparse has always been rather opaque to me. Using argparse helps a little.

    The insight that I think will help is that the optparse module doesn't actually help you perform the actions specified on the command line. Rather, it helps you collect information from the command line arguments, which you can act on later.

    In this case, the information you're collecting is stored in the tuple (options, args) in your line:

    (options, args) = parser.parse_args()
    

    To actually act on this information, you're going to have to do your own checking in your code. I like to put things like this in a block at the end of my program, which will only run if it is called from the command line.

    if __name__ == '__main__':
        if options.list:
            list_my_repos()
    

    To make how this works a little clearer, it helps to realize that you could do the same thing without optparse at all, by using sys.argv.

    import sys
    
    if __name__ == '__main__':
        if sys.argv[1] == '-l':
            list_my_repos()
    

    as you can probably see, however, this would be a very fragile implementation. Being able to handle more complex cases without doing too much of your own programming is what optparse/argparse buys you.