是否可以继承argparse子解析器中的必需选项?

时间:2019-07-10 23:13:51

标签: python-3.x argparse

我正在尝试编写一个命令行应用程序,它具有几种可以运行的模式(类似于git具有clonepull等)。我的每个子命令都有自己的选项,但是我也希望它们共享一组必需的选项,因此我尝试使用父解析器来实现这一点。但是,似乎继承了必需的选项会使子解析器不断要求它。这是重新创建行为的示例:

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选项成为必需,则此问题已解决,但是有没有一种方法可以在多个子解析器中共享所需的选项,而不仅仅是在每个子解析器中复制粘贴它们?还是我会以完全错误的方式来做这件事?

1 个答案:

答案 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粘贴操作,仅此而已。当父项在其他地方定义并导入时,它最有用。实际上,它是通过引用进行复制的,有时会引起问题。通常,同时运行父母和孩子不是一个好主意。使用“虚拟”父母。