18

这是一个示例代码:

import argparse

parser=argparse.ArgumentParser()
parser.add_argument('-main_arg')
subparser=parser.add_subparser()
a=subparser.add_parser('run')
a.add_argument('required_sub_arg')
a.add_argument('arg_a')
b=subparser.add_parser('b')
parser.parse_args()

-main_arg如果我输入,我希望它读入program run required_sub_arg -main_arg -arg_a

现在,它不被认为-main_arg是一个有效的论点。

4

2 回答 2

11

PSA 致最近的读者

由于这个问题在 2018 年仍然有访问,在使用 argparse 做任何复杂的事情之前,请考虑使用docoptclick代替。它将提高您和任何可能阅读或修改您的代码的人的理智。谢谢你。

原始答案

照原样,您有一些问题。

首先,parser.parse_args是一个返回parser参数命名空间的方法,所以你应该做类似的事情

args = parser.parse_args()

然后从一个电话args.main_args中得到-main_arg

program -main_arg run required_sub_arg -arg_a

您的问题main_arg是您已经为parsernamed创建了一个参数main_arg,并且您拨打了类似的电话

program run required_sub_arg -main_arg -arg_a

指的是anamed的一个参数main_arg。由于a没有这样的论据,它是无效的。

为了从其子解析器之一引用解析器的参数,您必须使所述子解析器继承其父级的参数。这是用

a=parser.add_subparser('run', parents=[parser])

您将子解析器误认为是子解析器。有关更多信息,请参阅http://docs.python.org/dev/py3k/library/argparse.htmlhttps://code.google.com/p/argparse/issues/detail?id=54

于 2011-08-15T16:12:45.377 回答
4

对于其他使用 argparse 的人到这里来寻找一种在“主”帮助屏幕中显示“通用”子解析器参数的方法,这是一种方法:

import argparse
common = argparse.ArgumentParser(add_help=False)
common.add_argument('--shared', action='store_true', help='some shared arg')
parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('--parent', action='store_true', help='parent only arg')
subparsers = parser.add_subparsers()
run = subparsers.add_parser('run', parents=[common])
run.add_argument('--fast', action='store_true', help='run only arg')
parser.epilog = "--- Arguments common to all sub-parsers ---" \
    + common.format_help().replace(common.format_usage(), '')
args = parser.parse_args()

主要帮助:

$ program.py -h
usage: program.py [-h] {run} ...

positional arguments:
  {run}

optional arguments:
  -h, --help  show this help message and exit
  --parent    parent only arg

--- Arguments common to all sub-parsers ---
optional arguments:
  --shared  some shared arg

run子解析器帮助:

$ program.py run -h
usage: program.py run [-h] [--shared]

optional arguments:
  -h, --help  show this help message and exit
  --shared    some shared arg
  --fast      run only arg

为了解决实际问题,由于接受的答案不适合我,这里有一些额外的信息,说明为什么在父和子/子解析器解析器之间真正共享具有相同名称的 argparse 参数似乎是不可能的。

首先,以下代码的问题:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-main_arg')
subparsers = parser.add_subparsers()
run = subparsers.add_parser('run', parents=[parser])
args = parser.parse_args()

是否会导致以下错误,因为父parser解析器和子解析器都run定义了 -h/--help 参数(默认情况下)。

Argparse.ArgumentError: argument -h/--help: conflicting option strings: -h, --help

add_help=False虽然可以通过在父级或子级上抑制 -h/--help 选项(带有 )来避免此错误,但在两个级别都有帮助选项是很好的。

避免冲突帮助选项的另一种潜在方法是将公共参数移动到共享解析器,common

import argparse
common = argparse.ArgumentParser(add_help=False)
common.add_argument('-main_arg', action='store_true')
parser = argparse.ArgumentParser(parents=[common])
subparsers = parser.add_subparsers()
run = subparsers.add_parser('run', parents=[common])
args = parser.parse_args()
print(args)

虽然这似乎在表面上起作用,但在实践中,它并没有按预期工作:

$ program.py run  # OK
Namespace(main_arg=False)
$ program.py run -main_arg  # OK
Namespace(main_arg=True)
$ program.py -main_arg run  # BAD: expected main_arg to be True
Namespace(main_arg=False)

解析时观察到的行为program.py -main_arg run说明了一个关键关系:父 argparser及其子解析器独立的解析器,其中解析器将所有参数解析到子解析器“命令”位置参数,然后选定的子解析器解析剩余的与父级在同一命名空间中的参数,不考虑父级可能已设置的属性。

于 2019-03-16T14:44:47.283 回答