分组 argparse 子解析器参数
Grouping argparse subparser arguments
我有一个包含多个命令的脚本,每个命令都有自己的一组必需 and/or 可选参数,使用 add_subparser.
=->test.py -h
usage: test.py [-h] <command> ...
positional arguments:
<command> Available Commands
cmd1 Command 1
cmd2 Command 2
cmd3 Command 3
cmd4 Command 4
optional arguments:
-h, --help show this help message and exit
=->test.py cmd1 -h
usage: test.py cmd1 [-h] --flag1 FLAG1
optional arguments:
-h, --help show this help message and exit
--flag1 FLAG1 Test flag
=->test.py cmd2 -h
usage: test.py cmd2 [-h] [--flag2 FLAG2]
optional arguments:
-h, --help show this help message and exit
--flag2 FLAG2 Test flag
我想以某种方式将这些命令分成几组,以便用户看到如下内容:
=->test.py -h
usage: test.py [-h] <command> ...
First Group:
cmd1 Command 1
cmd2 Command 2
Second Group:
cmd3 Command 3
cmd4 Command 4
optional arguments:
-h, --help show this help message and exit
但是,add_argument_group 和 add_subparser 似乎不能一起工作。
有什么方法可以实现吗?
你是对的,参数组和子解析器不能一起工作。那是因为子解析器(或者更确切地说是它们的名字)不是参数。
sp = parser.add_subparsers(...)
命令创建一个参数,或者从技术上讲是 argparse.Action
子类的一个实例。这是位置论证。 add_parser
命令创建一个 parser
对象(即调用 argparse.ArgumentParser
),并将它连同它的名称(和别名)添加到该操作拥有的字典中。名称填充操作的 choices
属性。
subparsers
操作可能属于参数组,但由于只能有一个这样的操作,因此它无法帮助您对帮助热线进行分组。
在某种程度上,您可以通过使用描述并省略子解析器的帮助来控制帮助
import argparse
description = """
First Group:
cmd1 Command 1
cmd2 Command 2
Second Group:
cmd3 Command 3
cmd4 Command 4"""
parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter)
sp = parser.add_subparsers(title='commands',description=description)
sp.add_parser('cmd1')
sp.add_parser('cmd2')
sp.add_parser('cmd3')
sp.add_parser('cmd4')
parser.print_help()
生产
1343:~/mypy$ python stack32017020.py
usage: stack32017020.py [-h] {cmd1,cmd2,cmd3,cmd4} ...
optional arguments:
-h, --help show this help message and exit
commands:
First Group:
cmd1 Command 1
cmd2 Command 2
Second Group:
cmd3 Command 3
cmd4 Command 4
{cmd1,cmd2,cmd3,cmd4}
http://bugs.python.org/issue9341 - 允许对 argparse 子命令进行分组
谈论做你想做的事。我提出的补丁并非微不足道。不过欢迎大家来测试一下。
我有这个问题,通过在父解析器中创建一个组和一个函数来解决它,它为给定子解析器的每个子解析器创建一个虚拟组,并将虚拟组的对象替换为想要的组,同时保留其地址,因此该组确实属于每个子解析器!
这是一个带有一点上下文的例子:
import argparse
import ctypes
parent_parser = argparse.ArgumentParser(description="Redacted")
subparsers = parent_parser.add_subparsers()
subparser_email = subparsers.add_parser("email", parents=[parent_parser], add_help=False)
subparser_gen = subparsers.add_parser("gen", parents=[parent_parser], add_help=False)
group_emails = subparser_email.add_argument_group("Main inputs")
group_gen = subparser_gen.add_argument_group("Emails generation")
group_matchers = parent_parser.add_argument_group("Matchers") # The group we want on each subparser
[...] # add the arguments to your groups here
def add_group_to_subparsers(group: argparse._ArgumentGroup, subparsers: argparse._SubParsersAction, name: str):
for name, subparser in subparsers._name_parser_map.items():
dummy_group = subparser.add_argument_group(name)
ctypes.memmove(id(dummy_group), id(group), object.__sizeof__(dummy_group))
add_group_to_subparsers(group_matchers, subparsers, "Matchers")
parent_parser.parse_args()
我有一个包含多个命令的脚本,每个命令都有自己的一组必需 and/or 可选参数,使用 add_subparser.
=->test.py -h
usage: test.py [-h] <command> ...
positional arguments:
<command> Available Commands
cmd1 Command 1
cmd2 Command 2
cmd3 Command 3
cmd4 Command 4
optional arguments:
-h, --help show this help message and exit
=->test.py cmd1 -h
usage: test.py cmd1 [-h] --flag1 FLAG1
optional arguments:
-h, --help show this help message and exit
--flag1 FLAG1 Test flag
=->test.py cmd2 -h
usage: test.py cmd2 [-h] [--flag2 FLAG2]
optional arguments:
-h, --help show this help message and exit
--flag2 FLAG2 Test flag
我想以某种方式将这些命令分成几组,以便用户看到如下内容:
=->test.py -h
usage: test.py [-h] <command> ...
First Group:
cmd1 Command 1
cmd2 Command 2
Second Group:
cmd3 Command 3
cmd4 Command 4
optional arguments:
-h, --help show this help message and exit
但是,add_argument_group 和 add_subparser 似乎不能一起工作。
有什么方法可以实现吗?
你是对的,参数组和子解析器不能一起工作。那是因为子解析器(或者更确切地说是它们的名字)不是参数。
sp = parser.add_subparsers(...)
命令创建一个参数,或者从技术上讲是 argparse.Action
子类的一个实例。这是位置论证。 add_parser
命令创建一个 parser
对象(即调用 argparse.ArgumentParser
),并将它连同它的名称(和别名)添加到该操作拥有的字典中。名称填充操作的 choices
属性。
subparsers
操作可能属于参数组,但由于只能有一个这样的操作,因此它无法帮助您对帮助热线进行分组。
在某种程度上,您可以通过使用描述并省略子解析器的帮助来控制帮助
import argparse
description = """
First Group:
cmd1 Command 1
cmd2 Command 2
Second Group:
cmd3 Command 3
cmd4 Command 4"""
parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter)
sp = parser.add_subparsers(title='commands',description=description)
sp.add_parser('cmd1')
sp.add_parser('cmd2')
sp.add_parser('cmd3')
sp.add_parser('cmd4')
parser.print_help()
生产
1343:~/mypy$ python stack32017020.py
usage: stack32017020.py [-h] {cmd1,cmd2,cmd3,cmd4} ...
optional arguments:
-h, --help show this help message and exit
commands:
First Group:
cmd1 Command 1
cmd2 Command 2
Second Group:
cmd3 Command 3
cmd4 Command 4
{cmd1,cmd2,cmd3,cmd4}
http://bugs.python.org/issue9341 - 允许对 argparse 子命令进行分组
谈论做你想做的事。我提出的补丁并非微不足道。不过欢迎大家来测试一下。
我有这个问题,通过在父解析器中创建一个组和一个函数来解决它,它为给定子解析器的每个子解析器创建一个虚拟组,并将虚拟组的对象替换为想要的组,同时保留其地址,因此该组确实属于每个子解析器!
这是一个带有一点上下文的例子:
import argparse
import ctypes
parent_parser = argparse.ArgumentParser(description="Redacted")
subparsers = parent_parser.add_subparsers()
subparser_email = subparsers.add_parser("email", parents=[parent_parser], add_help=False)
subparser_gen = subparsers.add_parser("gen", parents=[parent_parser], add_help=False)
group_emails = subparser_email.add_argument_group("Main inputs")
group_gen = subparser_gen.add_argument_group("Emails generation")
group_matchers = parent_parser.add_argument_group("Matchers") # The group we want on each subparser
[...] # add the arguments to your groups here
def add_group_to_subparsers(group: argparse._ArgumentGroup, subparsers: argparse._SubParsersAction, name: str):
for name, subparser in subparsers._name_parser_map.items():
dummy_group = subparser.add_argument_group(name)
ctypes.memmove(id(dummy_group), id(group), object.__sizeof__(dummy_group))
add_group_to_subparsers(group_matchers, subparsers, "Matchers")
parent_parser.parse_args()