Python command-line option parser
Just a note about the command-line parser in my iTunes python script. Back in Python 2.2 (Mac OS X 10.2) I needed a simpler and more versatile command-line parser than getopt, so I wrote commandline.py. Erik Osheim points out that I don’t need to use it any more: as of Python 2.3 there is a new command-line options parser called optparse that does everything I need, and it comes standard with Python 2.3 and greater.
It’s also easier to use and works better. Last weekend I took a close look at it and will be replacing commandline.py in my other scripts when I have time. Here’s a simple example of how it works, from a more recent script:
[toggle code]
- from optparse import OptionParser
- #set up command-line options
- parser = OptionParser()
- parser.add_option("-s", "--slug", help="start with page matching slug", metavar="SLUG", dest="pageslug")
- parser.add_option("-l", "--local", help="do not upload", default=True, action="store_false", dest="upload")
- parser.add_option("-r", "--no-recurse", help="do not publish child pages", default=True, action="store_false", dest="recurse")
- #grab options
- (options, args) = parser.parse_args()
-
#do web pages
-
if options.pageslug:
- page = getPageFromSlug(options.pageslug)
-
else:
- page = getPageFromPath("", host="www.hoboes.com")
-
if page:
- makePage(page, upload=options.upload, recurse=options.recurse)
-
else:
- print "Could not find a base page"
-
if options.pageslug:
This is from the publish script that I use to publish the on-line version of Negative Space from my local Django-managed database. It sets up three options:
- a “slug” option that tells the script to start with a specific page (identified by its “slug”);
- a “local only” flag that tells the script not to upload files to the server;
- a “do not recurse” flag that tells the script to do only the specified page and not any of its subpages.
Most of it is self-explanatory, but the “metavar” is the name used in the help for that option’s required text, and “dest” is the name of the property you’ll use to access the value of that option. You can see that I check “options.pageslug” to decide whether to start from a specific page or start from the home page, and I use options.upload and options.recurse to set those arguments in the “makePage” function.
The parser automatically sets up a “--help” option, and the “parse_args()” method automatically stops the script if --help is requested or if the user specifies invalid options.
Here is the help generated by the above script:
7: bin/publish -help usage: publish [options] options: -h, --help show this help message and exit -sSLUG, --slug=SLUG start with page matching slug -l, --local do not upload -r, --no-recurse do not publish child pages 8:
You can also specify a “type” for each option requiring that the value be a number or a choice from a list of choices.
One thing it doesn’t do, which I’d been hoping for (my commandline.py doesn’t do it either), is a “conditional default” that is conditional to the option being specified. For example, I have an option called “--upcoming” in my iTunes script that takes a number as its value: the number of upcoming tracks to display. I’d like to be able to specify --upcoming both with and without a number, applying a default of 10 only if --upcoming was specified on the command-line but was specified with no number.
This would of course be difficult to parse (it would need to determine whether it should or should not consume the next item on the command line) but would be useful. It might be possible to add this feature by extending the available actions, or perhaps I’m missing something in the on-line docs.
In response to Using appscript in Python to control GUI applications: The appscript module for Python lets you control scriptable applications on the command line without having to coordinate your command-line script with your Applescript applications.
- optparse—More powerful command line option parser
- “optparse is a more convenient, flexible, and powerful library for parsing command-line options than getopt. optparse uses a more declarative style of command-line parsing: you create an instance of OptionParser, populate it with options, and parse the command line. optparse allows users to specify options in the conventional GNU/POSIX syntax, and additionally generates usage and help messages for you.”
- Erik Osheim
- “Interests include tool-using, violence, computers, electricity, and romantic walks in the evening.”
- Django
- “Django is a high-level Python Web framework that encourages rapid development and clean, pragmatic design.” Oh, the sweet smell of pragmatism.
More Python
- Parsing JSKit/Echo XML comments files
- While I’m not a big fan of remote comment systems for privacy reasons, I was willing to use JSKit as a temporary solution because they provide an easy XML dump of posted comments. This weekend, I finally moved my main blog to custom comments; here’s how I parsed JSKit’s XML file.
- Put a relative clock on your Desktop with GeekTool
- There are a lot of desktop clocks that show the absolute time. But sometimes you just want to know if the time is today, or yesterday, or two days ago. Here’s how to do it with Python and GeekTool.
- Multiple tables on the same command
- The way the “random” script currently stands, it does one table at a time. Often, however, you have more than one table you know you’re going to need. Why not use one command to rule them all?
- Easier random tables
- Rather than having to type --table and --count, why not just type the table name and an optional count number?
- Programming for Gamers: Choosing a random item
- If you can understand a roleplaying game’s rules, you can understand programming. Programming is a lot easier.
- 24 more pages with the topic Python, and other related pages

You may be interested in a little Python module I wrote to make handling of command line arguments even easier (open source and free to use) - http://freshmeat.net/projects/commando
Mufasa at 2:19 p.m. February 6th, 2011
HCq51