原来以为python会自带这么一相模块,毕竟这是一个很普遍的需求,但查了一些有关python库的reference没有发现有这么个现成的库,在csdn的python版发帖询问了一下:http://topic.csdn.net/u/20101227/15/22408509-7d0d-4660-8d2c-b97822761abc.html?54614,同样没有结果.
工作还得继续,于是乎自己动手,丰衣足食. 代码如下:
def sf():
'''
just a test function
'''
pass
def menu_manage(menu_path_list, menu_dict):
'''
menu_path_list likes below:
menu_path_list = ['1st', '2nd', '3rd']
menu_dict likes below:
menu_dict = {
1 : ('system', 'test.py'),
2 : ('software', 'test.py'),
3 : ('user', function),
4 : ('network', function),
5 : ('1+1 redundancy', 'test.py'),
6 : ('snmp', function),
7 : ('logout', 'test.py'),
}
The output menu likes below:
1st -> 2nd -> 3rd:
1) system
2) software
3) user
4) network
5) 1+1 redundancy
6) snmp
7) logout
Select option number ( b>ack or l>ist ) (b) :
'''
#output menu
output_menu(menu_path_list, menu_dict)
ret = 0
while True:
#output input prompt
print ''
input_str = raw_input('Select option number ( b>ack or l>ist ) (b): ')
if input_str in ['', 'b']:
if len(menu_path_list) == 1:
#it is the root menu, just output this menu again
output_menu(menu_path_list, menu_dict)
continue
else:
#back to top menu
return 6
elif input_str in ['l']:
print ''
output_menu(menu_path_list, menu_dict)
continue
try:
option_number = int(input_str)
except ValueError:
print 'Error, input should be a number!'
continue
if option_number not in menu_dict:
print 'Error, input option is invalid!'
continue
menu_node = menu_dict[option_number][0]
if type(menu_dict[option_number][1]) == type(sf):
#it is a function
sub_menu_path_list = menu_path_list[:]
sub_menu_path_list.append(menu_node)
func = menu_dict[option_number][1]
ret = func(sub_menu_path_list)
else:
#it is a script
script_name = menu_dict[option_number][1]
module_name = script_name[:-3]
exec('import ' + module_name)
sub_menu_path_list = menu_path_list[:]
sub_menu_path_list.append(menu_node)
exec "ret = %s.main(%s)" % (module_name, sub_menu_path_list)
if ret == 6:
#exit from child menu, output parent menu again
output_menu(menu_path_list, menu_dict)
else:
#do nothing
pass
return 0
def output_menu(menu_path_list, menu_dict):
'''
menu_path_list likes below:
menu_path_list = ['1st', '2nd', '3rd']
menu_dict likes below:
menu_dict = {
1 : ('system', 'test.py'),
2 : ('software', 'test.py'),
3 : ('user', function),
4 : ('network', function),
5 : ('1+1 redundancy', 'test.py'),
6 : ('snmp', function),
7 : ('logout', 'test.py'),
}
The output menu likes below:
1st -> 2nd -> 3rd:
1) system
2) software
3) user
4) network
5) 1+1 redundancy
6) snmp
7) logout
'''
#output menu path
menu_path = ' -> '.join(menu_path_list)
print menu_path + ':'
#output menu body
for menu_key in sorted(menu_dict.keys()):
print '/t%d) %s' % (menu_key, menu_dict[menu_key][0])
return 0
下面是使用这模块的三个示例文件:
main_menu.py
import menu_util
def func_b(menu_path_list):
'''
'''
print 'print in func_b()'
return 0
root_menu_dict = {
1 : ('1st_a', 'sub_a.py'),
2 : ('1st_b', func_b),
}
if __name__ == '__main__':
menu_util.menu_manage(['root'], root_menu_dict)
sub_a.py:
import menu_util
def sub_sub_sub_a(menu_path_list):
print 'in sub_sub_sub_a()'
return 0
def sub_sub_sub_b(menu_path_list):
print 'in sub_sub_sub_b()'
return 0
def sub_sub_menu_a(menu_path_list):
'''
'''
sub_sub_menu_a_dict = {
1 : ('3rd_a', sub_sub_sub_a),
2 : ('3rd_b', sub_sub_sub_b),
}
return menu_util.menu_manage(menu_path_list, sub_sub_menu_a_dict)
sub_a_menu_dict = {
1 : ('2nd_a', sub_sub_menu_a),
2 : ('2nd_b', 'sub_sub_b.py'),
}
def main(menu_path_list):
'''
'''
return menu_util.menu_manage(menu_path_list, sub_a_menu_dict)
if __name__ == '__main__':
menu_util.menu_manage(['root'], root_menu_dict)
sub_sub_b.py:
def main(menu_path_list):
'''
'''
print 'in sub_sub_b.main()'
return 6
运行main_menu.py的结果如下:
[root@louis menu]# ./main_menu.py
root:
1) 1st_a
2) 1st_b
Select option number ( b>ack or l>ist ) (b): 1
root -> 1st_a:
1) 2nd_a
2) 2nd_b
Select option number ( b>ack or l>ist ) (b): 1
root -> 1st_a -> 2nd_a:
1) 3rd_a
2) 3rd_b
Select option number ( b>ack or l>ist ) (b): 1
in sub_sub_sub_a()
Select option number ( b>ack or l>ist ) (b): l
root -> 1st_a -> 2nd_a:
1) 3rd_a
2) 3rd_b
Select option number ( b>ack or l>ist ) (b): 2
in sub_sub_sub_b()
Select option number ( b>ack or l>ist ) (b): l
root -> 1st_a -> 2nd_a:
1) 3rd_a
2) 3rd_b
Select option number ( b>ack or l>ist ) (b): b
root -> 1st_a:
1) 2nd_a
2) 2nd_b
Select option number ( b>ack or l>ist ) (b): 2
in sub_sub_b.main()
root -> 1st_a:
1) 2nd_a
2) 2nd_b
Select option number ( b>ack or l>ist ) (b): b
root:
1) 1st_a
2) 1st_b
Select option number ( b>ack or l>ist ) (b): 2
print in func_b()
Select option number ( b>ack or l>ist ) (b):