Python argparse - 向多个子解析器添加参数
- 2025-04-01 09:56:00
- admin 原创
- 3
问题描述:
我的脚本定义了一个主解析器和多个子解析器。我想将-p
参数应用于一些子解析器。到目前为止,代码如下所示:
parser = argparse.ArgumentParser(prog="myProg")
subparsers = parser.add_subparsers(title="actions")
parser.add_argument("-v", "--verbose",
action="store_true",
dest="VERBOSE",
help="run in verbose mode")
parser_create = subparsers.add_parser ("create",
help = "create the orbix environment")
parser_create.add_argument ("-p",
type = int,
required = True,
help = "set db parameter")
# Update
parser_update = subparsers.add_parser ("update",
help = "update the orbix environment")
parser_update.add_argument ("-p",
type = int,
required = True,
help = "set db parameter")
如您所见,add_arument ("-p")
重复了两次。实际上,我还有更多子解析器。有没有办法循环遍历现有的子解析器以避免重复?
为了记录,我使用的是 Python 2.7
解决方案 1:
由@hpaulj 更新
由于自 2011 年以来处理子解析器的方式发生了变化,将主解析器用作 不是一个好主意parent
。更一般地说,不要尝试dest
在主解析器和子解析器中定义相同的参数(相同的 )。子解析器值将覆盖主解析器设置的任何内容(即使子解析器也default
会这样做)。创建单独的解析器以用作parents
。并且如文档中所示,父级应该使用add_help=False
。
原始答案
这可以通过定义包含公共选项的父解析器来实现:
import argparse
parent_parser = argparse.ArgumentParser(description="The parent parser")
parent_parser.add_argument("-p", type=int, required=True,
help="set db parameter")
subparsers = parent_parser.add_subparsers(title="actions")
parser_create = subparsers.add_parser("create", parents=[parent_parser],
add_help=False,
description="The create parser",
help="create the orbix environment")
parser_create.add_argument("--name", help="name of the environment")
parser_update = subparsers.add_parser("update", parents=[parent_parser],
add_help=False,
description="The update parser",
help="update the orbix environment")
这将产生以下格式的帮助信息:
parent_parser.print_help()
输出:
usage: main.py [-h] -p P {create,update} ...
The parent parser
optional arguments:
-h, --help show this help message and exit
-p P set db parameter
actions:
{create,update}
create create the orbix environment
update update the orbix environment
parser_create.print_help()
输出:
usage: main.py create [-h] -p P [--name NAME] {create,update} ...
The create parser
optional arguments:
-h, --help show this help message and exit
-p P set db parameter
--name NAME name of the environment
actions:
{create,update}
create create the orbix environment
update update the orbix environment
但是,如果您运行程序,则如果您未指定操作(即create
或update
),则不会遇到错误。如果您需要此行为,请按如下方式修改代码。
<...>
subparsers = parent_parser.add_subparsers(title="actions")
subparsers.required = True
subparsers.dest = 'command'
<...>
这个修复是在这个 SO 问题中提出的,它指的是跟踪拉取请求的问题。
解决方案 2:
接受的答案是正确的;正确的方法是使用父解析器。但是,示例代码在我看来并没有真正解决问题。让我补充几点意见,提供一个更合适的例子。
与接受的答案的主要区别在于明确可能有一些根级参数(如--verbose
)以及仅对某些子解析器共享的参数(-p
仅适用于create
和子update
解析器,但不适用于其他子解析器)
# Same main parser as usual
parser = argparse.ArgumentParser()
# Usual arguments which are applicable for the whole script / top-level args
parser.add_argument('--verbose', help='Common top-level parameter',
action='store_true', required=False)
# Same subparsers as usual
subparsers = parser.add_subparsers(help='Desired action to perform', dest='action')
# Usual subparsers not using common options
parser_other = subparsers.add_parser("extra-action", help='Do something without db')
# Create parent subparser. Note `add_help=False` and creation via `argparse.`
parent_parser = argparse.ArgumentParser(add_help=False)
parent_parser.add_argument('-p', help='add db parameter', required=True)
# Subparsers based on parent
parser_create = subparsers.add_parser("create", parents=[parent_parser],
help='Create something')
# Add some arguments exclusively for parser_create
parser_update = subparsers.add_parser("update", parents=[parent_parser],
help='Update something')
# Add some arguments exclusively for parser_update
这是顶级帮助消息(请注意-p
,这里未显示参数,这正是您所期望的 - 因为它特定于某些子解析器):
>>> parser.print_help()
usage: [-h] [--verbose] {extra-action,create,update} ...
positional arguments:
{extra-action,create,update}
Desired action to perform
extra-action Do something without db
create Create something
update Update something
optional arguments:
-h, --help show this help message and exit
--verbose Common top-level parameter
以及该操作的帮助信息create
:
>>> parser_create.print_help()
usage: create [-h] -p P
optional arguments:
-h, --help show this help message and exit
-p P add db parameter
解决方案 3:
您还可以循环遍历子解析器并向所有子解析器添加相同的选项。
parser = argparse.ArgumentParser(prog="myProg")
subparsers = parser.add_subparsers(title="actions")
parser.add_argument("-v", "--verbose",
action="store_true",
dest="VERBOSE",
help="run in verbose mode")
parser_create = subparsers.add_parser ("create",
help = "create the orbix environment")
parser_update = subparsers.add_parser ("update",
help = "update the orbix environment")
for subparser in [parser_create, parser_update]:
subparser.add_argument ("-p",
type = int,
required = True,
help = "set db parameter")
解决方案 4:
您可以按照以下方式循环遍历子解析器。
for name, subp in subparsers.choices.items():
print(subp)
subp.add_argument(dest='g', help='Input for g variable', default=7, type=int)
请注意,通过使用subparsers.choices
它可以避免对所有子解析器进行硬编码。