Python argparse - 向多个子解析器添加参数

发布于 2024-12-06 00:38:02 字数 1102 浏览 0 评论 0原文

我的脚本定义了一个主解析器和多个子解析器。我想将 -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

My script defines one main parser and multiple subparsers. I want to apply the -p argument to some subparsers. So far the code looks like this:

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

As you can see the add_arument ("-p") is repeated twice. I actually have a lot more subparsers. Is there a way to loop through the existing subparsers in order to avoid repetition?

For the record, I am using Python 2.7

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

终弃我 2024-12-13 00:38:02

由 @hpaulj 更新

由于自 2011 年以来处理子解析器的变化,使用主解析器作为是一个坏主意。更一般地说,不要尝试在主解析器和子解析器中定义相同的参数(相同的dest)。子解析器值将覆盖主解析器设置的任何内容(即使子解析器 default 也会这样做)。创建单独的解析器用作父级。如文档中所示,家长应使用 add_help=False


原始答案

这可以通过定义包含公共选项的 父解析器 来实现( s):

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更新)。如果您需要这种行为,请按如下方式修改您的代码。

<...>
subparsers = parent_parser.add_subparsers(title="actions")
subparsers.required = True
subparsers.dest = 'command'
<...>

此修复是在这个SO问题中提出的,它指的是跟踪拉取请求的问题。

Update by @hpaulj

Due to changes in handling subparsers since 2011, it is a bad idea to use the main parser as a parent. More generally, don't try to define the same argument (same dest) in both main and sub parsers. The subparser values will overwrite anything set by the main (even the subparser default does this). Create separate parser(s) to use as parents. And as shown in the documentation, parents should use add_help=False.


Original answer

This can be achieved by defining a parent parser containing the common option(s):

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

This produces help messages of the format:

parent_parser.print_help()

Output:

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

Output:

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

However, if you run your program, you will not encounter an error if you do not specify an action (i.e. create or update). If you desire this behavior, modify your code as follows.

<...>
subparsers = parent_parser.add_subparsers(title="actions")
subparsers.required = True
subparsers.dest = 'command'
<...>

This fix was brought up in this SO question which refers to an issue tracking a pull request.

信愁 2024-12-13 00:38:02

接受的答案是正确的;正确的方法是使用父解析器。然而,示例代码在我看来并没有真正解决问题。让我添加几分钱来提供一个更合适的例子。

与接受的答案的主要区别是明确可能有一些根级参数(如 --verbose)以及仅用于某些子解析器的共享参数(-p 仅适用于 createupdate 子解析器,但不适用于其他子解析器)

# 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 code> 参数此处未显示,这正是您想要的期望 - 因为它特定于某些子解析器):

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

The accepted answer is correct; the proper way is to use parent parsers. However, the example code IMO was not really solving the problem. Let me add my few cents to provide a more suitable example.

The main difference with accepted answer is the explicit possibility to have some root-level arguments (like --verbose) as well as shared arguments only for some subparsers (-p only for the create and update subparsers but not for others)

# 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 

This is the top-level help message (note that -p parameter is not shown here, which is exactly what you would expect—because it is specific to some subparsers):

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

And the help message for the create action:

>>> parser_create.print_help()
usage:  create [-h] -p P

optional arguments:
  -h, --help  show this help message and exit
  -p P        add db parameter
猫腻 2024-12-13 00:38:02

您还可以循环子解析器并向所有子解析器添加相同的选项。

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

You can also loop over the subparsers and add the same option to all of them.

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")
囍孤女 2024-12-13 00:38:02

您可以通过以下方式循环子解析器。

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 ,您可以避免对所有子解析器进行硬编码。

You can loop over your subparsers in the following way.

for name, subp in subparsers.choices.items():
    print(subp)
    subp.add_argument(dest='g', help='Input for g variable', default=7, type=int)

Note that by using subparsers.choices that you avoid needing to hard-code all of the subparsers.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文