我正在尝试编写一个命令行应用程序,它具有几种可以运行的模式(类似于git
具有clone
,pull
等)。我的每个子命令都有自己的选项,但是我也希望它们共享一组必需的选项,因此我尝试使用父解析器来实现这一点。但是,似乎继承了必需的选项会使子解析器不断要求它。这是重新创建行为的示例:
import argparse
parent_parser = argparse.ArgumentParser(description="The parent parser")
parent_parser.add_argument("-p", type=int, required=True,
help="set the parent required parameter")
subparsers = parent_parser.add_subparsers(title="actions", required=True, dest='command')
parser_command1 = subparsers.add_parser("command1", parents=[parent_parser],
add_help=False,
description="The command1 parser",
help="Do command1")
parser_command1.add_argument("--option1", help="Run with option1")
parser_command2 = subparsers.add_parser("command2", parents=[parent_parser],
add_help=False,
description="The command2 parser",
help="Do command2")
args = parent_parser.parse_args()
现在,如果我运行python test.py
,我将得到:
usage: test.py [-h] -p P {command1,command2} ...
test.py: error: the following arguments are required: -p, command
好的,到目前为止很好。然后,如果我尝试仅用-p
指定python test.py -p 3
选项,则会得到:
usage: test.py [-h] -p P {command1,command2} ...
test.py: error: the following arguments are required: command
但是如果我运行python test.py -p 3 command1
我得到:
usage: test.py command1 [-h] -p P [--option1 OPTION1] {command1,command2} ...
test.py command1: error: the following arguments are required: -p, command
如果我添加另一个-p 3
,它仍然要求再次指定command
,然后如果我再次添加它,则要求另一个-p 3
等。
如果我没有使-p
选项成为必需,则此问题已解决,但是有没有一种方法可以在多个子解析器中共享所需的选项,而不仅仅是在每个子解析器中复制粘贴它们?还是我会以完全错误的方式来做这件事?
答案 0 :(得分:1)
分离主解析器和父解析器功能:
import argparse
parent_parser = argparse.ArgumentParser(description="The parent parser", add_help=False)
parent_parser.add_argument("-p", type=int, required=True,
help="set the parent required parameter")
main_parser = argparse.ArgumentParser()
subparsers = main_parser.add_subparsers(title="actions", required=True, dest='command')
parser_command1 = subparsers.add_parser("command1", parents=[parent_parser],
description="The command1 parser",
help="Do command1")
parser_command1.add_argument("--option1", help="Run with option1")
parser_command2 = subparsers.add_parser("command2", parents=[parent_parser],
description="The command2 parser",
help="Do command2")
args = main_parser.parse_args()
主解析器和子解析器都写入相同的args
名称空间。如果两者都定义了“ p”参数,则子解析器的值(或默认值)将覆盖主设置的任何值。因此,可以在两者中使用相同的“目标”,但这通常不是一个好主意。并且每个解析器必须满足其自己的“必需”规范。没有“共享”。
parents
机制将参数从父级复制到子级。因此,它节省了键入或复制n粘贴操作,仅此而已。当父项在其他地方定义并导入时,它最有用。实际上,它是通过引用进行复制的,有时会引起问题。通常,同时运行父母和孩子不是一个好主意。使用“虚拟”父母。