Thinking about the best way to handle command registration

August 17, 2008

Suppose that you have a Python utility program that does a number of related things; it's invoked as 'program command ....', and decides what to do based on what the command is. The obvious way to implement this in Python is to have a function for each command and a top-level dispatcher that looks up the function to call for each command and passes it the arguments to process. Clearly you don't want to hard-code this in the dispatcher function in a big if/elif block; instead you want to somehow register all the commands in a simpler, easier to maintain way.

Since I have been writing such a utility program, I have found myself wondering what the best way of doing this is (where 'best' means 'most natural, obvious, and easy to follow'). So far I've come up with a number of possible ways:

  • have a dictionary where the key is the command name and the value is a tuple of information about the command (including the function to call, the minimum and maximum number of command line arguments it takes, and some help text).

    (The obvious and simple approach, but it starts getting more and more awkward as you add more per-command data to keep track of. You can use a structure instead of a tuple, but then you are complicating the simple scheme.)

  • call a registration function to define a command, giving it all of the details:
    def cmdfunc(args, ...):
    register('cmd', cmdfunc, ...)

    (The registration function can have defaults for various things.)

  • use a decorator function to do the registration:
    @register('cmd', ...)
    def cmdfunc(args, ...):

  • attach all of the information to the function as function attributes, and have a simple scheme to relate the command to the function name. The top level dispatcher then uses introspection to find if the command exists and to pull out anything else it needs.

Naturally you can combine aspects of all of these together to create hybrid systems (for example, using the function's docstring for some of the user help text).

Of these, I suspect that the decorator function approach is the most Pythonic but is also the second hardest for people who are not experienced Python programmers to follow (introspection would probably be the hardest). Since that last issue is a consideration, I am leaning towards using the plain registration function approach.

(My current code mostly uses the simple dictionary approach, but it's not the clearest thing to follow.)

Written on 17 August 2008.
« Why your blog comments have less of an audience than new blog entries
The problem with using tuples and lists to hold structures »

Page tools: View Source, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Sun Aug 17 23:38:03 2008
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.