随笔 - 41, 文章 - 8, 评论 - 8, 引用 - 0
数据加载中……

[python]用python实现文本菜单

昨天看c++,是关于代理类的。

而代理类的,则包含一整套有继承关系的类。

所以,我突发奇想,不如用继承来实现菜单。

思路是,有个menu类,然后派生,

一个用以放子菜单,

另一个用以实现绑定函数的菜单。

代码如下:

# -*- coding:utf-8 -*-

class Menu(object):
    def __init__(self,label):
        self.label=label

    def click(self):
        pass

class callbackMenu(Menu):
    def __init__(self,label,callback,father=None):
        self.label=label
        self.rcallback=callback
        self.rfather=father

    def click(self,*args,**kwds):
        print "currentClick",self.label
        print
        if callable(self.rcallback):
            self.rcallback(*args,**kwds)
        else:
            return None

class subMenu(Menu):
    def __init__(self,label,submenu,father=None):
        self.label=label
        self.rsubmenu=submenu
        self.rfather=father

    def show(self):
        for i,sub in enumerate(self.rsubmenu):
            print "[%d] %s"%(i,sub.label)
       

    def click(self):
        print "currentMenu",self.label
        self.show()

def showfather(p):
    if(hasattr(p,"rfather") and p.rfather==None):
        print p.label
        return
    print p.label,'<-',
    showfather(p.rfather)

def showfather2(p,symbol='->'):
    if p.rfather==None:
        print p.label,
        return
    showfather2(p.rfather,symbol)
    print symbol,p.label,


def handle(p):
    while True:
        print '-'*40
        showfather2(p)
        print
        p.click()
        try:
            get=raw_input("Input:")
            if get in ['q','Q']:
                break
            get=int(get)
            if get==100:
                if hasattr(p,"rfather") and p.rfather!=None:
                    p=p.rfather
                continue
            if isinstance(p.rsubmenu[get],callbackMenu):
                p.rsubmenu[get].click()
            elif isinstance(p.rsubmenu[get],subMenu):
                fp=p
                p=p.rsubmenu[get]
                p.rfather=fp
        except:
            print "Wrong Input"

if __name__=='__main__':
    sub=subMenu("sub",[callbackMenu("cb1",None),
            callbackMenu("cb2",None)])
    sub2=subMenu("sub2",[callbackMenu("cb2_1",None),
            callbackMenu("cb2_2",None)])
    sub3=subMenu(
            "sub3",
            [subMenu("subsub1",
                [callbackMenu("subcb1",None),
                    callbackMenu("subcb2",None)]),
            subMenu("subsub2",
                            [callbackMenu("sub2cb1",None),
                                callbackMenu("sub2cb2",None)])])
    main=subMenu("Main",[sub,sub2,sub3])
    handle(main)
在这里,我用输入100来返回上一级菜单。

现在想想,面向对象的设计真够难的。

第一步抽象就被卡住了。

在沉思录中,作者常常提示“用类来表示概念”。

但是,现在很犹豫,我的python版本的需不需要继承呢。

另外,引一句在C++编程规范里的,

继承,不是为了重用,而是为了被重用”。

我觉得非常有道理,因为我需要一个指针样的东西,

来处理各级菜单,如果提供的接口不一样,就很难用这个

指针了。

posted on 2011-02-02 12:12 mirguest 阅读(2395) 评论(0)  编辑 收藏 引用 所属分类: python


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理