简体   繁体   中英

optional python arguments without dashes but with additional parameters?

what I'd like to do in Python is accept arguments of the following format:

script.py START | STOP | STATUS | MOVEABS <x> <y> | MOVEREL <x> <y>

So in other words,

  1. I don't want to deal with hyphens;
  2. I have multiple possibilities, ONE of which is required;
  3. Each is mutually exclusive;
  4. Some of the commands (EG moveabs and moverel) have additional required arguments, but these args and should not be present with any other argument.

Can this be done in python and would I use argparse or something else? Thanks.

Using docopt you can do this quite easily.

Install docopt first:

$ pip install docopt

Write the script.py :

"""
Usage:
    script.py (start | stop | status | moveabs <x> <y> | moverel <x> <y>)
"""
from docopt import docopt

if __name__ == "__main__":
    args = docopt(__doc__)
    print args

and run it:

first showing basic help:

$ python script.py
Usage:
    script.py (start | stop | status | moveabs <x> <y> | moverel <x> <y>)

then try subcommands:

start

$ python script.py start
{'<x>': None,
 '<y>': None,
 'moveabs': False,
 'moverel': False,
 'start': True,
 'status': False,
 'stop': False}

stop

$ python script.py stop
{'<x>': None,
 '<y>': None,
 'moveabs': False,
 'moverel': False,
 'start': False,
 'status': False,
 'stop': True}

moveabs

$ python script.py moveabs 11 22
{'<x>': '11',
 '<y>': '22',
 'moveabs': True,
 'moverel': False,
 'start': False,
 'status': False,
 'stop': False}

moverel

$ python script.py moverel 11 22
{'<x>': '11',
 '<y>': '22',
 'moveabs': False,
 'moverel': True,
 'start': False,
 'status': False,
 'stop': False}

add_parser with subparsers would do the trick

import argparse
parser = argparse.ArgumentParser(prog='script.py')
sp = parser.add_subparsers(dest='cmd')
for cmd in ['START', 'STOP', 'STATUS']:
    sp.add_parser(cmd)
for cmd in ['MOVEABS', 'MOVEREL']:
    spp = sp.add_parser(cmd)
    spp.add_argument('x', type=float)
    spp.add_argument('y', type=float)
parser.print_help()
args = parser.parse_args()
print(args)

producing the likes of:

2137:~/mypy$ python2.7 stack23304740.py MOVEREL -h
usage: script.py [-h] {START,STOP,STATUS,MOVEABS,MOVEREL} ...

positional arguments:
  {START,STOP,STATUS,MOVEABS,MOVEREL}

optional arguments:
  -h, --help            show this help message and exit

usage: script.py MOVEREL [-h] x y

positional arguments:
  x
  y

optional arguments:
  -h, --help  show this help message and exit

and

2146:~/mypy$ python2.7 stack23304740.py MOVEREL 1.0 2.0
...
Namespace(cmd='MOVEREL', x=1.0, y=2.0)

and

2147:~/mypy$ python2.7 stack23304740.py START
...
Namespace(cmd='START')

The MOVEREL arguments could be named <x> and <y> , but then you'd have to access them via args['<y>'] instead of args.y . metavar='<x>' could be used to change the display but not the Namespace name.

You could also use spp.add_argument('point', nargs=2, type=float) . Unfortunately there's a bug that keeps us from using a metavar in this nargs=2 case, http://bugs.python.org/issue14074 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM