我是靠谱客的博主 激情胡萝卜,这篇文章主要介绍python argparse 子命令解析(续二),现在分享给大家,希望可以做个参考。

参考资料 http://docs.python.org/dev/library/argparse.html


子命令 sub-commands

如svn命令    svn checkout, svn update, svn commit

主命令svn,子命令checkout、update和commit

argparse可通过add_subparsers 以及add_parser来达到效果。

步骤1.在顶层的解析器下,先定义一个subparsers,它是一个子命令解析的对象,用来产生子命令解析器 (注意,每个解析器,只能有一个subparsers)

步骤2.在subparsers下,分别定义所需要的子解析器(一个subparsers下可以有多个parser),子解析器间是互斥的关系,一个时刻只能匹配一个。

实例1

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import argparse ####example 1############ #create top-level parser parser = argparse.ArgumentParser(prog='PROG') parser.add_argument('--foo', action='store_true', help='foo help') subparsers = parser.add_subparsers(help='sub-command help') #create the parser for the 'a' command parser_a = subparsers.add_parser('a', help='a help') parser_a.add_argument('bar', type=int, help='bar help') #create the parser for the 'b' command parser_b = subparsers.add_parser('b', help='b help') parser_b.add_argument('--baz', choices='xyz', help='baz help') #parse some argument lists parser.parse_args(['a','12']) #Namespace(bar=12, foo=False) parser.parse_args(['--foo', 'b','--baz','z']) #Namespace(baz='Z', foo=True) parser.parse_args(['--help']) #usage: PROG [-h] [--foo] {a,b} ... # #positional arguments: # {a,b} sub-command help # a a help # b b help # #optional arguments: # -h, --help show this help message and exit # --foo foo help parser.parse_args(['a','-h']) #usage: PROG a [-h] bar # #positional arguments: # bar bar help # #optional arguments: # -h, --help show this help message and exit parser.parse_args(['b','-h']) #usage: PROG b [-h] [--baz {x,y,z}] # #optional arguments: # -h, --help show this help message and exit # --baz {x,y,z} baz help

实例2

add_subparsers()可以添加title以及description的参数,还有dest参数(用来保存匹配出来的子解析器名)

此外,可以通过子命令解析器设置默认值set_defaults()来达到子解析器与功能函数对应关系

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
###########example 2 ################ #添加子命令函数 def foo(args): print (args.x * args.y) def bar(args): print ('((%s))' %args.z) #创建最上层解析器 parser = argparse.ArgumentParser() subparsers = parser.add_subparsers(title='subcommands', description='valid subcommands', help='additional help', dest='subparser_name') #创建子解析器 'foo' 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) #将函数foo 与子解析器foo绑定 #创建子解析器‘bar' parser_bar = subparsers.add_parser('bar') parser_bar.add_argument('z') parser_bar.set_defaults(func=bar) #将函数bar与子解析器bar绑定 args = parser.parse_args('foo 1 -x 2'.split()) #Namespace(func=<function foo at 0xd6ae60>, subparser_name='foo', x=2, y=1.0) args.func(args) #2.0 args = parser.parse_args('bar xyzyz'.split()) #Namespace(func=<function bar at 0xd6aed8>, subparser_name='bar', z='xyzyz') args.func(args) #((xyzyz)) parser.parse_args(['-h']) #usage: subparser_example.py [-h] {foo,bar} ... # #optional arguments: # -h, --help show this help message and exit # #subcommands: # valid subcommands # # {foo,bar} additional help

注意:

子解析器下还可以定义孙子解析器


3.实际应用例子(参考openstack cinder-manage)

现在要求有一个manager, 有 db 以及host两个子命令

db命令可以有update(更新数据库) 以及sync操作(同步数据库)

host命令可以有list操作(列出host信息)

分析

db 以及host是互斥关系,因此db 和host为子命令

而db下的update 和sync命令又是互斥关系,因此它两为db的子命令

因此全局解析器分三层,顶层,子层(db、host) 以及孙子层db.sync,db.update 和host.list

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import argparse def args(*args,**kwargs): def _decorator(func): func.__dict__.setdefault('args', []).insert(0, (args,kwargs)) return func return _decorator class Dbcommands(object): def __init__(self): pass @args('version', nargs='?', default='versiondefault', help='version help') def sync(self, version=None): print "do Dbcommand.sync(version=%s)." %version def update(self): print "do Dbcommand.update()." class Hostcommands(object): @args('zone', nargs='?', default="zonedefault", help=' zone help') def list(self,zone=None): print "do Hostcomands.list(zone=%s)." %zone def methods_of(obj): result = [] for i in dir(obj): if callable(getattr(obj, i)) and not i.startswith('_'): result.append((i, getattr(obj, i))) return result def fetch_func_args(func,matchargs): fn_args = [] for args,kwargs in getattr(func, 'args', []): arg = args[0] fn_args.append(getattr(matchargs, arg)) return fn_args CATEGORIES = { 'db' : Dbcommands, 'host': Hostcommands} if __name__ == "__main__": top_parser = argparse.ArgumentParser(prog='top') subparsers = top_parser.add_subparsers() for category in CATEGORIES: command_object = CATEGORIES[category]() category_parser = subparsers.add_parser(category) category_parser.set_defaults(command_object=command_object) category_subparsers = category_parser.add_subparsers(dest='action') for (action, action_fn) in methods_of(command_object): parser = category_subparsers.add_parser(action) action_kwargs = [] for args, kwargs in getattr(action_fn, 'args', []): parser.add_argument(*args, **kwargs) parser.set_defaults(action_fn=action_fn) parser.set_defaults(action_kwargs=action_kwargs) match_args = top_parser.parse_args('db sync 3'.split()) print 'match_args:',match_args fn = match_args.action_fn fn_args = fetch_func_args(fn,match_args) #do the match func fn(*fn_args)

运行结果

复制代码
1
2
>>match_args: Namespace(action='sync', action_fn=<bound method Dbcommands.sync of <__main__.Dbcommands object at 0x7f67a8b1cbd0>>, action_kwargs=[], command_object=<__main__.Dbcommands object at 0x7f67a8b1cbd0>, version='3') do Dbcommand.sync(version=3).


最后

以上就是激情胡萝卜最近收集整理的关于python argparse 子命令解析(续二)的全部内容,更多相关python内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(53)

评论列表共有 0 条评论

立即
投稿
返回
顶部