2015-09-28 110 views
0

我想写我的python脚本解析其中的命令参数应该按以下顺序解析嵌套的可选参数,argsparse在蟒蛇

OUTPUT: cli unmount [-h] -f FS_NAME [-n NODE_SPEC] [--evict [--force]]]

我能编写除最后一个之外的其余命令的代码。 [--evict [--force]]。这意味着--force参数仅适用于给出--evict的情况。

parser = argparse.ArgumentParser('CLI demo') 
sub_parser = parser.add_subparsers() 
unmount = sub_parser.add_parser('unmount') 
unmount.add_argument("-f", "--fs", dest="fs_name", required=True, help="filesystem name.") 
unmount.add_argument("-n", "--nodes", dest="nodes", metavar='NODE_SPEC', help="pdsh style nodes hostnames (If this parameters ") 

这些都是我已添加的可选子的说法,--force到可选父的说法,--evict两种方法,

方法1:

evict_parser = unmount.add_subparsers() 
evict = evict_parser.add_parser("--evict", help="evict lustre clients before unmount.") 
evict.add_argument("--force", dest="force", action="store_true", default=False, help="force mode for evict lustre clients.") 
parser.parse_args() 

方法2:

parent_cmd_parser = argparse.ArgumentParser(add_help=F) 
parent_cmd_parser.add_argument("--force", dest="force", action="store_true", default=False, help="force mode for evict lustre clients.") 
evict_parser = unmount.add_subparsers() 
evict = evict_parser.add_parser("--evict", help="evict lustre clients before unmount.", parents=[parent_cmd_parser]) 

不幸的是没有工作。在第一种情况下,我没有得到所需的帮助输出/使用帮助,在第二种情况下--force参数被隐藏。

+0

如果'--force'没有使用'--evict',会发生什么?如果首先给出呢? – hpaulj

+0

@hpaulj,在这种情况下,这将是错误的。因为只有在启用了--evict时才会启用--force。 –

回答

1

​​不直接支持相互依赖的参数。

只需添加--force定期说法,文档,它仅适用于当--evict,并给出了当--force使用没有--evict给出一个错误:

if args.force and not args.evict: 
    parser.error('--force can only be used together with --evict') 
+0

我不明白'直接支持独立参数'是什么意思?这是否意味着它为另一个参数添加了一个子参数? –

+0

@BhupeshPant:是的,'相互依赖'是指依赖于其他论点的论据。 –

+0

哦,我明白了,感谢您的快速回复。 –

0

另一种选择是用nargs='?'定义--evict ,并定义defaultconst

parser.add_argument('--evict', nargs='?', default='noEvict', const='EvictWOArgument') 

然后args.evict将是 'noEvict', 'EvictWOArgument',或什么都串了用户(如 '力')。您可以选择任何方便的值和解释。你甚至可以使用“选择”:

In [2]: parser=argparse.ArgumentParser()  
In [4]: parser.add_argument('-e','--evict',nargs='?',choices=['force'],default=False, const=True) 

In [5]: parser.parse_args([]) 
Out[5]: Namespace(evict=False) 

In [6]: parser.parse_args(['-e']) 
Out[6]: Namespace(evict=True) 

In [7]: parser.parse_args(['-e','test']) 
usage: ipython3.5 [-h] [-e [{force}]] 
ipython3.5: error: argument -e/--evict: invalid choice: 'test' (choose from 'force') 
... 

In [8]: parser.parse_args(['-e','force']) 
Out[8]: Namespace(evict='force') 

如果http://bugs.python.org/issue9334补丁曾经被使用过,有可能定义“--force”作为choice。目前解析器在解析时很早就分类,如字符串选项标志。这种用法也可能会让最终用户感到困惑 - --force是一个可以随处去的可选项,或者是一个必须遵循--evict的参数?

+0

感谢您的回复@hpaulj。这当然可以帮助我达到我的目的。但我仍然陷入一件事。当我尝试用这行代码执行parser.parse_args(['unmount',' - f file_node',' - evict','--force'])时,出现错误,unmount_parser.add_argument(' - -evict',nargs ='?',choices = [' - force'],default = False,const = True)。但是,当我用武力代替 - 强制其工作。我想要武力。这是因为我不想破坏现有的功能。 –

+0

对,解析器将''--force''字符串视为可选标记,而不是作为参数。有一个积压的补丁(9334),它会添加一个'args_default_to_positional'参数来改变这种行为。 – hpaulj