Python argparse - 为多个子分析器添加参数

rah*_*hmu 60 python argparse

我的脚本定义了一个主解析器和多个子解析器.我想将这个-p论点应用于一些subparser.到目前为止代码看起来像这样:

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")
Run Code Online (Sandbox Code Playgroud)

如你所见,add_arument ("-p")重复两次.我实际上有更多的subsparsers.有没有办法循环遍历现有的子分析符以避免重复?

为了记录,我使用的是Python 2.7

Sve*_*ach 76

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

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")
Run Code Online (Sandbox Code Playgroud)

  • 从[文档](https://docs.python.org/3/library/argparse.html#sub-commands):"当从子分析程序请求帮助消息时,仅打印该特定分析器的帮助帮助消息不包括父解析器或兄弟解析器消息." 这似乎是这一战略的一个主要缺点. (14认同)
  • 我认为它表现异常的原因是“父解析器”实际上与“带有子解析器的解析器”不是同一回事。(请注意,文档永远不会同时显示这两个功能)十分确定,您需要一个顶级解析器,一个单独的带有全局args的“父”解析器,以及前一个将其“ parents =”设置为的子解析器。后者。 (4认同)
  • @RyneEverett:该手册部分令人困惑,可能已过时,因为它似乎至少在Python 3.5.3子解析器中--help包含来自父解析器的参数。 (2认同)

The*_*her 8

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

可接受答案的主要区别在于,明确的可能性是--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 
Run Code Online (Sandbox Code Playgroud)

这是顶级帮助消息(请注意,-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
Run Code Online (Sandbox Code Playgroud)

以及该操作的帮助消息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
Run Code Online (Sandbox Code Playgroud)

  • 这是一个非常清晰的例子,这个答案需要更多人的支持。 (3认同)

小智 7

您也可以遍历子分析器并为所有子分析器添加相同的选项.

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")
Run Code Online (Sandbox Code Playgroud)

  • 我认为这是一个不好的方法,因为您需要循环遍历参数。Sven Marnach的答案更加干燥和实用。 (2认同)

Ger*_*ool 7

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

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

请注意,通过使用subparsers.choices它,您可以避免对所有子解析器进行硬编码。

  • @craymichael 不完全是。类似的,我给你。区别在于可迭代。JanK 的答案使用解析器列表,我的答案使用 subparsers.choices.items()。subparsers.choices.items() 的优点是 subparsers.choices.items() 始终包含所有使用的子解析器。使用列表时,您必须在添加或删除子解析器时更改它。我确实必须赞扬 Jank 的想法,我只是更进一步,因为我不喜欢硬编码和维护列表。 (4认同)