2013-10-22 71 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'是子命令,其餘的是那個子命令的參數,並且都可以被要求。 –