2017-09-03 39 views
0

我正在玩Python的​​模块,以获得一个相当复杂和庞大的子命令结构。到目前为止,参数解析得很好,一切正常,但我正在寻找更好的方法来管理如何执行子命令。调度Python的argparse子命令的最佳方式

这里是我的虚拟/ playaround应用的一个例子:

def a_func(cmd_args): 
    print(cmd_args) 


def b_func(cmd_args): 
    print(cmd_args) 


CMD_DISPATCHER = { 
    'a': a_func, 
    'b': b_func 
} 


def parse_commands(): 
    # Create top-level parser 
    parser = argparse.ArgumentParser() 
    subparsers = parser.add_subparsers(dest='subcmd_name') 

    # Create parser for the "a" sub-command 
    parser_a = subparsers.add_parser('a') 
    parser_a.add_argument('-bar', type=int) 

    # Create parser for the "b" sub-command 
    parser_b = subparsers.add_parser('b') 
    parser_b.add_argument('-foo', type=int) 

    args = parser.parse_args() 

    CMD_DISPATCHER[args.subcmd_name](args) 


def main(): 
    parse_commands() 


if __name__ == '__main__': 
    main() 

正如你所看到的,在这里我用一个简单dictCMD_DISPATCHER)作为与子命令名称,它的功能的地图。

正如我所说的,这只是我想要实现的一个简单例子,但真正的项目会有很多嵌套的子命令,所以我想要一个更好的方法来管理这几个子命令。

你知道更好/更专业的方法吗?

+0

in [ruamel.std.argparse](https://pypi.python.org/pypi/ruamel.std.argparse)我使用装饰器将'Cmd'类的方法注册到子分析器中。这些方法的其他装饰器用于选项。还有一种定义“全局”选项的特殊方法(适用于所有的子分析器)。 – Anthon

回答

1

好的,在进行了一些研究之后,我发现了一个适合我需求的好方法:set_defaults。我早些时候使用过这个函数,但总是设置默认的现有默认参数值。我没有注意到明显的例子是argparse documentation规定:

>>> # sub-command functions 
>>> def foo(args): 
...  print(args.x * args.y) 
... 
>>> def bar(args): 
...  print('((%s))' % args.z) 
... 
>>> # create the top-level parser 
>>> parser = argparse.ArgumentParser() 
>>> subparsers = parser.add_subparsers() 
>>> 
>>> # create the parser for the "foo" command 
>>> parser_foo = subparsers.add_parser('foo') 
>>> parser_foo.add_argument('-x', type=int, default=1) 
>>> parser_foo.add_argument('y', type=float) 
>>> parser_foo.set_defaults(func=foo) 
>>> 
>>> # create the parser for the "bar" command 
>>> parser_bar = subparsers.add_parser('bar') 
>>> parser_bar.add_argument('z') 
>>> parser_bar.set_defaults(func=bar) 
>>> 
>>> # parse the args and call whatever function was selected 
>>> args = parser.parse_args('foo 1 -x 2'.split()) 
>>> args.func(args) 
2.0 
>>> 
>>> # parse the args and call whatever function was selected 
>>> args = parser.parse_args('bar XYZYX'.split()) 
>>> args.func(args) 
((XYZYX)) 

正如你可以看到parser_bar.set_defaults(func=bar)设置一个新的变量parser_bar参数就行了。在这种情况下,bar是最终用作行args.func(args)中的子命令执行程序的函数。

我希望这可以帮助未来的人。

相关问题