There's a Python module that I recently became obsessed with called
cmd (Python docs). You can use it to give your Python programs a shell interface. For some reason, I never knew about this module for a long time, but once I learned about it, I began using it a lot to build some awesome utilities.
Python is one of my favorite languages because it lets you write lots of cool utilities and scripts for getting stuff done. For most small scripts, I'll just pass input as command line arguments but sometimes I'll want something a little more interactive and to give me instant feedback and to maintain a state. That's where the
cmd module really makes it easy to write powerful Python scripts that appeal to my "power user" side.
If you were to do this on your own, you would probably write something like this:
while in_command_loop: raw_input = input("Prompt>") if input == 'command_1': command_1() elif input == 'command_2': command_2() # more commands here... else: print "Error"
So that's not too terrible. We loop and get commands as input and run functions. One problem is that we'll spend some time updating this loop when we want to add a new command and that's just another
if statement in this thing. Not elegant. We can do better. We're Python developers.
First thing to know about
cmd.Cmd: you subclass it and customize the subclass to be your command prompt. The methods of this subclass that begin with
do_ are now your prompt commands. Here's a trivial example:
from cmd import Cmd class MyPrompt(Cmd): def do_hello(self, args): """Says hello. If you provide a name, it will greet you with it.""" if len(args) == 0: name = 'stranger' else: name = args print "Hello, %s" % name def do_quit(self, args): """Quits the program.""" print "Quitting." raise SystemExit if __name__ == '__main__': prompt = MyPrompt() prompt.prompt = '> ' prompt.cmdloop('Starting prompt...')
Running that gives the following:
Starting prompt... > help Documented commands (type help <topic>): ======================================== hello help quit > help hello Says hello. If you provide a name, it will greet you with it. > hello austin Hello, austin >
Cool things to notice about this:
- Self documenting commands: Your prompt contains an implicit
help command which will show you some help text for the command. Where does that come from? It's your method doc string!
- Command history: You you press the up and down keys and scroll through a list of commands. Some OS shells already do this for you, but it's still a nice feature.
- Organization: All of your commands are just methods and they all have a command method signature. I like how comfortable this feels compared to a massive block of
if... elif... else statements.
- Lots of features: I didn't touch any of the really neat things, like pre-command and post-command code being executed.
So in conclusion, the
cmd module lets you build a command line shell for your Python program without a lot of extra effort. You get to keep using the command line (like all real geeks use) and get some interactivity.