2013-10-22 40 views
1
import ArgumentParser 

parser = ArgumentParser(description="Tool to keep archiving tar files") 
parser.add_argument("-a", "--action", dest="action", choices=("start", "stop", "list"), help="start/stop/list the directories to be monitored", default="list", required=True) 
parser.add_argument("-t", "--type", dest="type", choices=("a", "b"), help="Type of spooler job", default=None) 
parser.add_argument("-p", "--path", dest="path", help="Absolute path of the directory to be monitored", default=None) 
parser.add_argument("-c", "--codeline", dest="codeline", choices=("x","y","z"), default=None, required=True) 
parser.add_argument("-r", "--release", dest="release", help="Directory path gets assigned automatically based on the release", default=None) 

args = parser.parse_args() 

在上面的代码中,如果动作被指定为start/stop,则type和path/release中的一个是必需的输入。有没有办法在add_argument方法本身做到这一点?如何在python中对命令行参数进行分组?

附加信息:
如果该操作以“列表”形式给出,则不需要其他选项。例如,“script.py -a列表”应该工作。 只有当动作以开始/停止的形式给出时,其他选项才是必需的。例如,“script.py -a start”应该抛出错误。 “script.py -a启动-TA -p/tmp目录-CX”“script.py -a开始-tb -r RR -cy”应该工作

+1

您可能需要使用subparser:http://docs.python.org/2/library/argparse.html#sub-commands。 – sberry

回答

1

如果使用add_subparsers(dest='action'),创造liststartstop subparsers,各有所需的参数(没有为list),根据需要以下输入会工作。 (注意-a未使用)。

script.py list 
script.py start # fail with insufficient arguments 
script.py start -t a -p /tmp -c x 
script.py start -t b -r rr -c y 

,扩大了我的建议:

from argparse import ArgumentParser 

parser = ArgumentParser(description="Tool to keep archiving tar files") 
sub = parser.add_subparsers(dest='action') 
sp1 = sub.add_parser('start') 
sp2 = sub.add_parser('stop') 
sp3 = sub.add_parser('list') 
#parser.add_argument("-a", "--action", dest="action", choices=("start", "stop", "list"), help="start/stop/list the directories to be monitored", default="list", required=True) 
for sp in [sp1,sp2]: 
    sp.add_argument("-t", "--type", dest="type", choices=("a", "b"), help="Type of spooler job", default=None) 
    sp.add_argument("-p", "--path", dest="path", help="Absolute path of the directory to be monitored", default=None) 
    sp.add_argument("-c", "--codeline", dest="codeline", choices=("x","y","z"), default=None, required=True) 
    sp.add_argument("-r", "--release", dest="release", help="Directory path gets assigned automatically based on the release", default=None) 

for astr in [ 
    'list', 
    'start -t a -p /tmp -c x', 
    'start -t b -r rr -c y', 
    'start']: 
    print parser.parse_args(astr.split()) 

结果是:

Namespace(action='list') 
Namespace(action='start', codeline='x', path='/tmp', release=None, type='a') 
Namespace(action='start', codeline='y', path=None, release='rr', type='b') 
usage: stack19510774.py start [-h] [-t {a,b}] [-p PATH] -c {x,y,z} 
           [-r RELEASE] 
stack19510774.py start: error: argument -c/--codeline is required 

如果-cstop没有意义,然后从它的参数设置忽略它。

有很多关于使用子分析器的SO问题。

+0

以上作品。但**“script.py stop -t -p/tmp”**不起作用。感谢您的帮助 – Hema

1

只需创建一个argument group

parser = ArgumentParser(description="Tool to keep archiving tar files") 

group = parser.add_argument_group('some group') 
group.add_argument("-a", "--action", dest="action", choices=("start", "stop", "list"), help="start/stop/list the directories to be monitored", default="list", required=True) 
group.add_argument("-t", "--type", dest="type", choices=("a", "b"), help="Type of spooler job", default=None) 
group.add_argument("-p", "--path", dest="path", help="Absolute path of the directory to be monitored", default=None) 
group.add_argument("-r", "--release", dest="release", help="Directory path gets assigned automatically based on the release", default=None) 

parser.add_argument("-c", "--codeline", dest="codeline", choices=("x","y","z"), default=None, required=True) 
+0

如果该操作以“列表”形式给出,则不需要其他选项。例如,script.py -a列表。只有当动作以开始/停止的形式给出时,其他选项才是必需的。例如,“script.py -a start”应该会引发错误。 “script.py -a start -t a -p/tmp -c x”或“script.py -a start -t b -r rr -c y”应该可以工作 – Hema

+1

@Hema:那听起来像是一个潜在的子命令, 'script.py start'是子命令,其余的是那个子命令的参数,并且都可以被要求。 –