我想要一个带有子解析器的程序,它可以处理特定的参数,同时还保留一些位置和可选参数给以前的解析器(事实上我真正想要的只有一个选项,我的意思是一个有效的子解析器或一个有效的本地参数)。
我希望拥有的东西的例子:Program [{sectionName [{a,b}]}] [{c,d}]。如果提供了 sectionName,则 c/d 不兼容,反之亦然。
Program [{sectionName [{a,b}]}] [{c,d}]
但是,我能实现的最好的结果就是这样test.py [-h] {sectionName} ... [{c,d}]。这意味着,argparse 不允许我在未指定有效的情况下使用位置参数 c 或 d sectionName。
test.py [-h] {sectionName} ... [{c,d}]
sectionName
以下是代码:
import argparse mainparser = argparse.ArgumentParser() # Subparser subparser = mainparser.add_subparsers(title="section", required=False) subparser_parser = subparser.add_parser("sectionName") subparser_parser.add_argument("attribute", choices=['a', 'b'], nargs='?') # Main parser positional and optional attributes mainparser.add_argument("attribute", choices=['c', 'd'], nargs='?') mainparser.parse_args()
我快被这个问题搞疯了。任何帮助我都会非常感激!
你可以通过一些调整实现你想要的功能。argparse 并不直接支持在主解析器和子解析器之间共享位置参数或让它们互相排斥,但可以通过以下方式实现逻辑:
argparse
添加互斥逻辑:手动检查解析结果,确保 sectionName 和主解析器的 attribute 不同时存在。
attribute
使用条件逻辑解析:根据输入的第一个参数决定是否进入子解析器。
以下是实现的代码示例:
import argparse def main(): mainparser = argparse.ArgumentParser(prog="Program") subparser = mainparser.add_subparsers(dest="section", help="section name (optional)") # Subparser for sectionName subparser_parser = subparser.add_parser("sectionName", help="subparser for sectionName") subparser_parser.add_argument("attribute", choices=['a', 'b'], help="attribute for sectionName") # Main parser positional and optional attributes mainparser.add_argument("attribute", choices=['c', 'd'], nargs='?', help="attribute for main parser") # Parse arguments args = mainparser.parse_args() # Validate mutual exclusivity if args.section == "sectionName" and args.attribute: mainparser.error("Cannot specify both 'sectionName' and main attribute ('c' or 'd').") # Handle parsed arguments if args.section == "sectionName": print(f"Section: sectionName, Attribute: {args.attribute}") else: print(f"Main Attribute: {args.attribute}") if __name__ == "__main__": main()
$ python test.py sectionName a Section: sectionName, Attribute: a
$ python test.py c Main Attribute: c
$ python test.py sectionName a c usage: Program [-h] {sectionName} ... [attribute] Program: error: Cannot specify both 'sectionName' and main attribute ('c' or 'd').
dest
在 add_subparsers 中指定 dest,让 args.section 存储用户选择的子解析器名称。
add_subparsers
args.section
手动验证冲突:
使用 args.section 和 args.attribute 检查两者是否冲突。
args.attribute
友好的错误消息:
mainparser.error
这种方法满足了你对互斥逻辑的需求,同时保持了灵活性。