Automatically registering “commands” for a command line program in python

StackOverflow https://stackoverflow.com/questions/4642373

  •  09-10-2019
  •  | 
  •  

سؤال

I would like to develop a command-line program that can process and give "help" for subcommands. To be concrete, say I have a single script called "cgent" and I would like to have subcommands "abc", "def", and "xyz" execute and accept the rest of the sys.args for processing by optparse.

cgent abc [options] 
cgent help abc
....

All of this is straightforward if I hard-code the subcommand names. However, I would like to be able to continue to add subcommands by adding a class or module (?). This is similar to the idea that is used by web frameworks for adding controllers, for example. I have tried digging through pylons to see if I can recreate what is done there, but I have not unravelled the logic. Any suggestions on how to do this?

Thanks, Sean

هل كانت مفيدة؟

المحلول

You'll have to create a "command registry". This can be as simple as a dictionary.

In the main program you do:

commands = {}

And in any submodules you add you do

from yourmodule.main import commands

def mynewcommand(arguments=here):
    pass

commands['newcommand'] = mynewcommand

Then you can use argparse to handle the commands. In which case your module needs to add the subparser part for the command too.

نصائح أخرى

If you don't have to do complex parsing of arguments I recommend the baker module. It lets you define subcommands and their arguments through decorators. For example:

#!/usr/bin/env python
import baker

@baker.command()
def foo(a=1):
    print 'foo:', a

@baker.command()
def baz(b=1):
    print 'baz:', b

baker.run()

defines the two subcommands foo and baz, with (optional) parameters a and b. So you can use them like this:

$ ./test_baker.py foo --a 2
foo: 2
$ ./test_baker.py baz
baz: 1

It also uses the docstrings to generate the help.

Since the baker module is global, your subcommands can span several .py files. As long as they are imported, the subcommands will be automatically registered.

Moreover it is just a single .py file so you can just drop it in your source tree.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top