Domanda

I'm using the argh library to create a python command line tool. Several of the names I'm using have turned out to be pretty long, e.g.:

./my_program.py download-and-parse-data --randomize-order --training-percent 80

Is there a simple way to allow abbreviations? For example, here's a potential abbreviated version of the above line.

./my_program.py dpd -r -t 80

Ideally, I'd like to be able to use both command-line forms -- the long, informative version, as well as the short, easy-to-type version. Is there a good way to do this?

È stato utile?

Soluzione

You can do this quite easily with argparse's add_subparsers() method. See the docs here.

In your case It might break down to this:

parser = argparse.ArgumentParser()
subs = parser.add_subparsers()
dpd = subs.add_parser('download-and-parse-data', aliases=['dpd'])
dpd.add_argument(...)
...

EDIT

In each add_argument() call you can also use multiple argument names. See docs here. E.g:

parser.add_argument('-f', '--foo')

Altri suggerimenti

While the argparse answer was accepted, the original question was how to accomplish this with the simpler argh module. Here's how:

from argh import *
from show import show # only needed for demonstration purposes

CMD_ALIASES = { 'dpd' : 'download-and-parse-data',
                'dp'  : 'download-and-parse-data',
                'dd'  : 'download-data',
                'pd'  : 'parse-data', }

def choices_for(d):
    """
    Return list of unique items (command aliases plus unabridged commands).
    Works in Python >= 2.5. NB In the degenerate case when an alias and an
    unabridged command are identical, the alias takes priority. (In my best
    Terminator voice: Don't do dat.)
    """
    return sorted(set(d.keys()) | set(d.values()))

@arg('cmd', choices=choices_for(CMD_ALIASES))
@arg('-r', '--randomize-order', default=False)
@arg('-t', '--training-percent', default=0)
def main(args):
    args.command = CMD_ALIASES.get(args.cmd, args.cmd)
    show(args, props=True)

dispatch_command(main)

This sets up a slightly generalized aliasing mechanism (one that allows multiple aliases for any given command). The resulting args object has both an args.cmd value for the command actually given, and a canonical args.command value that resolves the given alias, if any.

For example:

$ ./my_program.py dpd -r -t 80
args:
    cmd='dpd'
    command='download-and-parse-data'
    randomize_order=True
    training_percent=80

There is also another mechanism built into argh to do command aliases if you are dispatching commands to individual functions: the @aliases decorator, described here. NB this approach has a dependency on recent versions of argparse, so may not work in older Python distributions/environments.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top