对于其他使用 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及其子解析器是独立的解析器,其中父解析器将所有参数解析到子解析器“命令”位置参数,然后选定的子解析器解析剩余的与父级在同一命名空间中的参数,不考虑父级可能已设置的属性。