在python中,如何在父解析器的参数中读取子分析器?

use*_*2pi 14 python argparse

这是一个示例代码:

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

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

现在,它不承认-main_arg是一个有效的论点.

Evp*_*pok 9

PSA给最近的读者

由于这个问题在2018年仍有访问,在使用argparse做任何复杂的事情之前,请考虑使用docopt点击.它将改善您的理智以及可能阅读或修改您的代码的任何人的理智.谢谢.

原始答案

原样,你有一些问题.

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

args = parser.parse_args()
Run Code Online (Sandbox Code Playgroud)

然后从像这样的电话args.main_args获得-main_arg

program -main_arg run required_sub_arg -arg_a
Run Code Online (Sandbox Code Playgroud)

你的问题main_arg是你已经创建了一个parser名为的参数main_arg,你打电话就像

program run required_sub_arg -main_arg -arg_a
Run Code Online (Sandbox Code Playgroud)

指的是a命名的参数main_arg.由于a没有这样的论点,它是无效的.

为了从其中一个subparser引用解析器的参数,你必须让所述subparser继承其父级的参数.这是完成的

a=parser.add_subparser('run', parents=[parser])
Run Code Online (Sandbox Code Playgroud)

你有错误的subsparser for child parser.有关更多信息,请参阅http://docs.python.org/dev/py3k/library/argparse.htmlhttps://code.google.com/p/argparse/issues/detail?id=54.


Gar*_*ett 6

对于使用 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()
Run Code Online (Sandbox Code Playgroud)

主要帮助:

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

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

为了解决实际问题,由于接受的答案不适合我,这里有一些附加信息,说明为什么似乎不可能在父解析器和子解析器解析器之间真正共享具有相同名称的 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()
Run Code Online (Sandbox Code Playgroud)

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

Argparse.ArgumentError: argument -h/--help: conflicting option strings: -h, --help
Run Code Online (Sandbox Code Playgroud)

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

避免帮助选项冲突的另一种潜在方法是将公共参数移至共享解析器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)
Run Code Online (Sandbox Code Playgroud)

虽然这表面上看起来可行,但实际上,它并没有按预期工作:

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

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