[Python-Dev] getopt helper?

M.-A. Lemburg mal@lemburg.com
Thu, 30 Sep 1999 13:22:27 +0200


Mark Hammond wrote:
> 
> > > Basically _every_ time I use getopt, I write code like this:
> 
> > Why not just add a higher level interface ? Something
> > like CommandLine.py which is included in mxDateTime ?
> 
> Because _every_ time I use getopt, I write code like that :-)
> 
> A higher level interface would maybe be handy, but it simply occurred
> to me that every time I used the module I used that pattern.  I just
> got sick of typing it all the time and wondered if it struck a chord
> with anyone else (and I dont have or use a general purpose "mhutil"
> module :-)  Im really just trying to save myself 10 lines of
> boilerplate coding, not introduce a new standard module :-)

Just a thought :-)

I wrote the CommandLine.py for pretty much the same reason: I
have quite a few command line apps lying in my bin/ dir and
they all did some kind of getopt/sys.argv tricks to handle
the input... way to confusing and not easy to maintain. So I
decided to take an OO-approach to have them use the same
interface with nice help output and to reduce the coding effort.

As an example taken from mxDateTime:

#!/usr/local/bin/python -u

""" Simple Forking Alarm

    Sample Application for DateTime types and CommandLine. Only works
    on OSes which support os.fork().

    Author: Marc-Andre Lemburg, mailto:mal@lemburg.com
"""
import time,sys,os
from mx.DateTime import *
from CommandLine import Application,ArgumentOption

class Alarm(Application):

    header = "Simple Forking Alarm"
    options = [ArgumentOption('-s',
                              'set the alarm to now + arg seconds'),
               ArgumentOption('-m',
                              'set the alarm to now + arg minutes'),
               ArgumentOption('-a',
                              'set the alarm to ring at arg (hh:mm)'),
               ]
    version = '0.1'

    def main(self):

        atime = now() + (self.values['-s'] or 
                         self.values['-m'] * 60 or 
                         self.values['-h'] * 3600) * oneSecond
        abs = self.values['-a']
        if abs:
            atime = strptime(abs,'%H:%M',today(second=0))
        if atime < now():
            print 'Alarm time has expired...'
            return
        print 'Alarm will ring at',atime
        if not os.fork():
            time.sleep((atime - now()).seconds)
            alarm()
            os._exit(0)

def alarm():

    """ Ring alarm
    """
    for i in range(10):
        sys.stdout.write('\007')
        sys.stdout.flush()
        time.sleep(0.2)

if __name__ == '__main__':
    Alarm()

Here's the help output this produces:

/home/lemburg> alarm -h
------------------------------------------------------------------------
Simple Forking Alarm
------------------------------------------------------------------------

Synopsis:
 alarm [option] files...

Options and default settings:
  -s arg       set the alarm to now + arg seconds
  -m arg       set the alarm to now + arg minutes
  -a arg       set the alarm to ring at arg (hh:mm)
  -h           show this help text
  --help       show this help text
  --copyright  show copyright
  --examples   show examples of usage

Version:
 0.1

-- 
Marc-Andre Lemburg
______________________________________________________________________
Y2000:                                                    92 days left
Business:                                      http://www.lemburg.com/
Python Pages:                           http://www.lemburg.com/python/