三级菜单:

1. 运行程序输出第一级菜单

2. 选择一级菜单某项,输出二级菜单,同理输出三级菜单

3. 菜单数据保存在文件中

4. 让用户选择是否要退出

5. 有返回上一级菜单的功能

类定义:menu_class.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# author : Wang Yue
#menu class
#定义菜单类,属性使用的实例属性,没有使用类属性,类属性共享给全部实例,会有问题的,这是百度才知道。
class menu_level(object):
    def __init__(self,real_name,real_my_id,real_parent_id):
        self.name=real_name #菜单名称
        self.my_id=real_my_id #菜单id
        self.parent_menu_id=real_parent_id #上级菜单id
        self.child_menu=[] #子菜单实例集合
        self.here = False  # means hold one 用户所在位置

#以下是一系列的属性操作方法
    def put_name(self,real_name):
        self.name=real_name
    def get_name(self):
        return self.name
    def put_my_id(self,real_my_id):
        self.my_id=real_my_id
    def get_my_id(self):
        return self.my_id
    def put_par_id(self,real_par_id):
        self.parent_menu_id=real_par_id
    def get_par_id(self):
        return self.parent_menu_id
    def put_here_true(self):
        self.here=True
    def put_here_false(self):
        self.here=False
    def get_here(self):
        return self.here
    def get_child(self):
        return self.child_menu
    def set_child(self,child):
        self.child_menu=child
    def append_child(self,menu_child):
        self.child_menu.append(menu_child)

入口程序:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# author : Wang Yue
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# author : Wang Yue

#主函数:进行各种业务的入口
#导入具体各个方法逻辑的文件,和sys库
import menu_fuc,sys

#运行时,需要知道运行方式。
if __name__ == "__main__":
    menu=menu_fuc.init_menu() #类初始化实例
    p_menu=menu_fuc.init_child(menu,0) #整理菜单,0为根,弄成一个菜单列表,有层级的,列表中的元素是最上的根。

    print(">>{_name}".format(_name=p_menu[0].get_name())) #按照需求,运行程序就打印根路径名称
    while True:
        #用循环维持整体操作环境
        #提供以下命令:
        #1、view,显示当前所在位置的路径,就是面包屑
        #2、next 菜单名称,到相应的菜单去
        #3、back,返回上一级菜单
        #4、tree,列出完整的菜单树
        #5、quit,退出程序
        # cmd is "view |next #name|back|tree|quit" view:where am i | next #name:where are you go | back:back to sup menu| tree list all menu|quit is exit
        cmd=input("MENU CMD:")
        if cmd =="view":
            name_que=menu_fuc.view_menu(menu) #列出当前所在完整路径,面包屑
            last_name=name_que[-2]
            for name in name_que:
                print("{_name}".format(_name=name),end=">>>")
                if name==last_name:
                    print(name_que[-1])
                    break
        elif "next" in cmd:
            cmd_go=cmd.split() #进入某一级菜单,根据菜单名称,不仅仅是下级。随意切换
            name=cmd_go[1]
            menu_fuc.next_menus(name,menu) #按照需求,当进入某一级后,要列出下级所有菜单名称
            menu_fuc.next_menu(menu,name) #进入下级的执行代码的方法函数
        elif cmd=="back":
            menu_fuc.back_menu(menu) #返回上级的方法函数
        elif cmd == "tree":
            menu_fuc.tree_menu(p_menu,">>") #列出完整菜单树的方法函数
        elif cmd == "quit" :
            sys.exit(0)
        else:
            cmd_help='''
            my menu CMD:
            view:where am i(view Current path)
            next #name:where are you go (go to #name menu)
            back:back to parent menu
            tree:list all tree
            quit:exit menu
            提供以下命令:
            1、view,显示当前所在位置的路径,就是面包屑
            2、next 菜单名称,到相应的菜单去
            3、back,返回上一级菜单
            4、tree,列出完整的菜单树
            5、quit,退出程序            
            '''

            print(cmd_help)

业务程序处理:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# author : Wang Yue
import menu_class,re
#初始化用户菜单的各个实例
def init_menu():
    menu_list=[]
    with open("menu_db.doo",mode="r",encoding="utf-8") as menu_db:
        menu_db.flush()
        menu_db.seek(0)
        lines=menu_db.readlines()
        for line_m in lines:
            line_f=line_m.strip()
            line=re.split(',',line_f)
            menu_cl=menu_class.menu_level(line[1],int(line[0]),int(line[2]))
            menu_list.append(menu_cl)
    return menu_list

#将子节点集合存入相应的父菜单实例的child列表中
def init_child(menu_list,pid):
    p_menu=[]
    for menu_one in menu_list:
        # print("my id is:{_name}".format(_name=menu_one.get_my_id()))
        if menu_one.get_par_id() == pid:
            p_menu.append(menu_one)
    for ppp in p_menu:
        get_sub_node(menu_list,ppp)
    return p_menu
def get_sub_node(menu_list,p_node): #上一个方法中,会调用此方法,寻找下级的子节点,利用递归一层一层查找
    for menu_child in menu_list:
        if p_node.get_my_id() == menu_child.get_par_id():
            # print(menu_child.get_name())
            p_node.append_child(menu_child)
            get_sub_node(menu_list,menu_child)


def get_back_menu(menu,menu_here,menu_que): #返回上级路径的方法
    for menu_one in menu:
        if menu_here.get_par_id() == menu_one.get_my_id():
            menu_que.append(menu_one)
            if menu_one.get_par_id() != 0:
                get_back_menu(menu,menu_one,menu_que)
    return menu_que

def view_menu(menu): #查看当前所在路径。
    menu_name_que=[]
    temp_que=[]
    menu_que=[]
    for menu_one in menu:
        if menu_one.get_here():#find which menu
            menu_que=get_back_menu(menu,menu_one,temp_que)
            menu_que.insert(0,menu_one)
            break
    menu_que.reverse()
    for my_menu in menu_que:
        menu_name_que.append(my_menu.get_name())
    return menu_name_que





def next_menu(menu,name): #进入下一级路径。
    for menu_one in menu:
        if menu_one.get_name()==name:
            menu_one.put_here_true()
            menu_next=menu_one
        elif menu_one.get_here():
            menu_one.put_here_false()

def back_menu(menu): #返回上级菜单
    for menu_one in menu:
        if menu_one.get_here():
            menu_one.put_here_false()
            for menu_two in menu:
                if menu_two.get_my_id() == menu_one.get_par_id():
                    menu_two.put_here_true();

def tree_menu(menu,logo): #显示完整菜单树,也是递归方法
    m=logo
    # root = tree_assembly(menu, p_id)
    for menu_root in menu:
        print(m+menu_root.get_name())
        if len(menu_root.get_child()) > 0:
            tree_menu(menu_root.get_child(),logo+m)

def next_menus(now_menu_name,menu): #在进入下级菜单时,显示下级全部菜单。
    for which_menu in menu:
        if which_menu.get_name() == now_menu_name:
            now_menu=which_menu
    ne_menu = now_menu.get_child()
    for ne_one in ne_menu:
        print(">>>{_name}".format(_name=ne_one.get_name()))

 

附:数据文件:

1,中国,0
2,河北,1
3,安徽,1
4,黑龙江,1
5,辽宁,1
6,山东,1
7,内蒙古,1
8,石家庄,2
9,济南,6
10,青岛,6
11,呼伦贝尔,7
12,锡林郭勒,7
13,二连浩特,7
14,海加尔,7
15,承德,2
16,合肥,3
17,哈尔滨,4
18,吉林,5
19,长春,5
20,临沂,6