带有多级解析器/子解析器的 Argparse 可选参数 [英] Argparse optional arguments with multilevel parser/subparser

查看:25
本文介绍了带有多级解析器/子解析器的 Argparse 可选参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一组解析器和子解析器来构建生产或开发系统.如果用户选择生产,他可以添加选项,一切都很好.
如果他拍摄开发,他可以输入架构,然后输入构建选项.这是它变得粘稠的地方.我希望他能够选择构建选项 'comms' 'server' 或 'all',但如果他选择服务器,他有更多的选择.

I have a set of parsers and subparsers to build a production or development system. If the user picks production, he can add options and all is well.
If he pics development, he can enter an architecture and then enter build options. This is where it gets sticky. I want him to be able to select build option 'comms' 'server' or 'all', but if he picks server, he has more choices.

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

My implementation is below. I tried combinations of parsers and subpasers (it seems that arguments can only be added to parsers, not subparsers, is that correct?)

它崩溃的原因有两个:
1)我只能选择arch或build,我需要同时选择
2)如果我选择构建,它总是要求我选择服务器",即使我选择其他两个之一.

It falls apart for 2 reasons:
1) I can only select arch or build and I need to select both
2) If I select build it always requires that I pick 'server', even if I pick one of the other two.

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

So I would like something like this ./buildServer.py Dev arch -arm build -comms or ./buildServer.py Dev arch -arm build -server -tcp

我将不胜感激,我可以得到帮助/指导 - TIA

I'd appreciate and help/guidance I can get - TIA

代码:

def verify():

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()  

推荐答案

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

aparser.add_argument(...) creates an Action class object, actually a subclass specified by the action parameter. That action/argument may be positional or optional (flagged).

sp=aparse.add_subparsers(...)add_argument 的特殊版本,它创建子解析器类的 Action.print(sp) 会显示它的一些属性.这实际上是一个 positional 参数,带有 choices 属性.

sp=aparse.add_subparsers(...) is specialized version of add_argument that creates an Action of the subparser class. print(sp) will show some of its attributes. This is actually a positional argument, with a choices attribute.

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

p1 = sp.add_parser(...) creates an argparse.ArgumentParser() object, and links it to a name that is placed in the sp.choices list. The parser is returned as the p1 variable.

p1.add_argument(...) 定义一个动作/参数,就像在主解析器中所做的一样.

p1.add_argument(...) defines a Action/argument, just as done with the main parser.

因此,在解析过程中,输入 (sys.argv) 会像往常一样一一处理.但是当它遇到一个在p1"的位置和名称上匹配的字符串时,解析任务被传递到 p1(带有 sys.argv 列表的剩余部分).当 p1 到达 sys.argv 的末尾时,它的命名空间和控制被传递给父解析器.父级不做任何进一步的解析.

So during parsing, the inputs (sys.argv) are handled one by one, as is usual. But when it hits a string that matches in position and name of a "p1", the parsing task is passed on to p1 (with what remains of the sys.argv list). When p1 has reached the end of sys.argv its namespace and control is passed to the parent parser. The parent doesn't do any further parsing.

在您的情况下,您可以向下传递多个级别的解析器.(术语,解析器和子解析器可能有点混乱,至少在描述中.它们在代码中明确定义.)

In your case you can pass down through several levels of parsers. (the terms, parser and subparsers can be a bit confusing, at least in the description. They are clearly defined in the code.)

这种子解析器机制只允许一个选择(在每个级别).这不是多级树横向工具.你沿着一个特定的线程结束,然后备份.

This subparser mechanism allows only one choice (at each level). This isn't a multilevel tree transversal tool. You go down one particular thread to end, and back up.

这样

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

./buildServer.py Dev arch -arm build -comms or ./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 用法不允许多个子解析器(只是您展示的嵌套).

There may be ways of working around this - I or others have suggested things like this in previous SO - but the straight forward argparse usage does not allow for multiple subparsers (just the nesting that you show).

这篇关于带有多级解析器/子解析器的 Argparse 可选参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆