argparse 用于解析 python 中嵌套的可选参数

argsparse for parsing nested optional arguments in python

我正在尝试为我的 python 脚本编写解析,其中命令参数应按以下顺序排列,

输出: 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

所采用的两种方法

方法一:

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()

方法二:

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])

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

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

只需添加 --force 作为 常规 参数,记录它仅在给出 --evict 时适用,并在 [=12= 时给出错误] 在没有 --evict 的情况下使用:

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

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

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

然后 args.evict 将是 'noEvict'、'EvictWOArgument' 或用户提供的任何字符串(例如 'force')。您可以选择任何方便的值和解释。你甚至可以使用 'choices':

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?

之后的参数?