带有多级解析器/子解析器的Argparse可选参数

问题描述 投票:0回答:1

我有一组解析器和子解析器,用于构建生产或开发系统。如果用户选择生产,则可以添加选项,一切都很好。如果他开发照片,则可以输入架构,然后输入构建选项。这就是它变粘的地方。我希望他能够选择构建选项“ comms”,“ server”或“ all”,但是如果他选择服务器,他还有更多选择。

我的实现如下。我尝试了解析器和子贴子的组合(似乎只能将参数添加到解析器中,而不能添加到子解析器中,对吗?)

它分崩离析有两个原因:1)我只能选择拱门或建筑,我需要同时选择两者2)如果我选择构建,则即使我选择其他两个之一,也总是要求我选择“服务器”。

所以我想要这样的东西./buildServer.py Dev arch -arm build -comms要么./buildServer.py Dev arch -arm build -server -tcp

我会很感激,能得到我的帮助/指导-TIA

代码:

def verify():

main_parser = argparse.ArgumentParser()     
main_subparsers = main_parser.add_subparsers(title="main", dest="main_command")          

# parser production choices                                                                                                     
prod_parser = main_subparsers.add_parser("prod", help="Prod")     
prod_parser.add_argument("-c",  "--change",   action='store_true', dest="change_sig", default=False, help="Change signature information (default = %(default)s)")
prod_parser.add_argument("-sd", "--sign-deb",  action='store_true', dest="sign_deb",   default=False, help="Add signature to the .deb file (default = %(default)s)")
prod_parser.add_argument ("-i",  "--install",  action='store_true', dest="build_deb" , default=False, help="Build .deb file from existing structure (default = %(default)s)")

# parser for development                                                                                                   
dev_parser = main_subparsers.add_parser("Dev", help="Dev")                                                                                                              
dev_subparser = dev_parser.add_subparsers(title="devsubparser")     

# optional development architecture choices
action_arch_parser = dev_subparser.add_parser("arch", help="architecture")
dev_arch_group = action_arch_parser.add_mutually_exclusive_group()
dev_arch_group.add_argument("-x86",  action='store_const', dest="architecture", const='x', default='x',help="Build dev code on X86")
dev_arch_group.add_argument("-arm",  action='store_const', dest="architecture",     const='a', help="Build dev code on arm")

# development build choices - 2 arguments (coms / all) and a third (server) that has its own options.
dev_build_parser = dev_subparser.add_parser("build", help="build")
dev_build_parser.add_argument("-comms", action='store_true',  help="Build comms program")
dev_build_parser.add_argument("-all", action='store_true',  help="Build all programs")
server_parser = dev_build_parser.add_subparsers(title="server", help="server subparser")
server_parser_p = server_parser.add_parser("server", help="server parser")
server_parser_p.add_argument("-tcp", help="tcp option")
server_parser_p.add_argument("-fips", help="fips option")
server_parser_p.add_argument("-sim", help="sim option")


args = main_parser.parse_args()  
python argparse optional-arguments subparsers
1个回答
0
投票

aparser.add_argument(...)创建一个Action类对象,实际上是action参数指定的子类。该动作/参数可以是positionaloptional(已标记)。

sp=aparse.add_subparsers(...)add_argument的专用版本,它创建了子解析器类的Actionprint(sp)将显示其某些属性。这实际上是一个positional参数,具有choices属性。

p1 = sp.add_parser(...)创建一个argparse.ArgumentParser()对象,并将其链接到sp.choices列表中放置的名称。解析器作为p1变量返回。

p1.add_argument(...)定义一个动作/参数,就像使用主解析器一样。

因此,在解析期间,输入(sys.argv)像往常一样被一一处理。但是,当它命中位置和名称与“ p1”相匹配的字符串时,解析任务将传递给p1(带有sys.argv列表的剩余内容)。当p1到达sys.argv的末尾时,其名称空间和控制权将传递给父解析器。父级不做任何进一步的解析。

根据您的情况,您可以向下传递多个层次的解析器。 (至少在描述中,术语,解析器和子解析器可能会有些混乱。它们在代码中已明确定义。)

此子解析器机制仅允许一个选择(在每个级别)。这不是多级树横向工具。您沿着某个特定线程结束并备份。

如此

./ buildServer.py Dev arch -arm build -comms或./buildServer.py Dev arch -arm build -server -tcp

main_parser   (sees 'Dev', passes control to:)
    dev_parser   (sees 'arch', passes control to:)
        action_arch_parser
            (sees -arm - sets the const)
            (doesn't have any positional to handle 'build'
                  returns with an unrechognized arguments)

[可能有解决此问题的方法-我或其他人在以前的SO中曾建议过类似的事情-但直接使用argparse不允许使用多个子解析器(只是显示的嵌套)。

© www.soinside.com 2019 - 2024. All rights reserved.