Creating Python class wrapper for a command line tool

Edvard Majakari edvard+news at majakari.net
Wed May 26 07:58:32 EDT 2004


Hi,

I was wondering what would be the most elegant way for creating a Python class
wrapper for a command line utility, which takes three types of arguments:

1. options with values (--foo=bar)

2. boolean options (--squibble)

3. data lines (MUNGE:x:y:z:frob)

So, when you call the program from command line it looks like

command --foo=bar --hip=hurray --squibble --optimize \
   MUNGE1:x1:y:z:frob1 \
   MUNGE2:x2:y:z:frob2 \
   MUNGE3:x3:y:z:frob3

and it produces something. The idea is to make class with methods for
setting the options and data, and then calling write() after all options
have been set. 

My current model is like this:

class Wrapper:

    def __init__(self, **kwargs):
        """Initialize object"""

        opts = []

        for key, val in kwargs.items():
            if isinstance(val, str) and val.find(' ') > -1:
                val = '"%s"' % val
            opts.append("--%s %s" % (key.replace('_', '-'), val))

    def setbool(self, opt):
        pass

    def data(self, data):
        pass

    def write(self):
        pass


The init method might look a bit odd; the reason is that I thought to call
Wrapper like this:

obj = Wrapper(use_bar=foo, treshold=10, name="alley cat")

and __init__() would transform those keyword parameters to long string
of the form '--use_bar foo --threshold 10 --name "alley cat"'

However, using **kwargs I cannot use boolean values, because a key in a
dictionary must have a value. Using parameter boolean=True would transform
to --boolean 1, which is not correct. That's why I added a separate method
setbool(), but that doesn't seem nice. To wrap the command line call

command --optimize --use_bar foo --threshold 10 --name "alley cat" \
   MUNGE1:x1:y:z:frob1 \
   MUNGE2:x2:y:z:frob2 \
   MUNGE3:x3:y:z:frob3

obj = Wrapper(use_bar=foo, treshold=10, name="alley cat")
obj.setbool('optimize')
obj.data("MUNGE1:x1:y:z:frob1")
obj.data("MUNGE2:x2:y:z:frob2")
obj.data("MUNGE3:x3:y:z:frob3")

This is acceptable, but I'm sure many of you professional Pythonistas have
a more elegant solution. What do you think?

-- 
# Edvard Majakari		Software Engineer
# PGP PUBLIC KEY available    	Soli Deo Gloria!

$_ = '456476617264204d616a616b6172692c20612043687269737469616e20'; print
join('',map{chr hex}(split/(\w{2})/)),uc substr(crypt(60281449,'es'),2,4),"\n";




More information about the Python-list mailing list