argparse声明全局参数后无法获取subparser_name如何解决
问题根因
你将已经定义了subparsers的顶层主解析器作为父解析器传给子解析器,子解析器会继承父解析器的子解析器配置,导致解析流程中,顶层主解析器给subparser_name赋值后,子解析器处理参数时没有匹配到下一级子命令,会将subparser_name覆盖为None。
修复方案
将全局公共参数单独抽取为无subparsers的独立父解析器,主解析器和子解析器按需继承该公共解析器即可,避免嵌套继承带子解析器的解析器。
修正后的代码如下:
import argparse import logging # 独立公共参数解析器:仅存放共用参数,不添加subparsers common_parser = argparse.ArgumentParser(add_help=False) common_parser.add_argument('-d', '--debug', action='store_true', help='debug flag') # 主解析器:负责挂载子命令 main_parser = argparse.ArgumentParser(prog="my_prog") subparsers = main_parser.add_subparsers( dest="subparser_name", help='some help notes', required=True # 可选配置:禁止用户不输入子命令直接执行 ) # 子解析器继承公共参数解析器即可拿到全局参数 parser_cmd1 = subparsers.add_parser('cmd1', parents=[common_parser]) # 注意长参数需要两个短横杠,原写法`-foo`为错误格式 parser_cmd1.add_argument('-f', '--foo', type=str, required=False, help='foo command') parser_cmd2 = subparsers.add_parser('cmd2', parents=[common_parser]) parser_cmd2.add_argument('-b', '--bar', type=str, required=False, help='bar command') args = main_parser.parse_args() subparser_name = args.subparser_name print(args) if args.debug: logging.basicConfig(level=logging.INFO) if subparser_name == 'cmd1': if args.foo: # 执行cmd1对应逻辑 pass if subparser_name == 'cmd2': if args.bar: # 执行cmd2对应逻辑 pass
修改后执行my_prog.py cmd1 -d -f inp_str,subparser_name就会正常返回cmd1。
补充说明
原代码中将解析器变量parser重新赋值为子命令名称,容易引发变量混淆,建议修改为单独的变量名(如示例中的subparser_name)。
内容的提问来源于stack exchange,提问作者Oneiros
相关产品推荐
相关产品推荐

