昨天看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++编程规范里的,
“继承,不是为了重用,而是为了被重用”。
我觉得非常有道理,因为我需要一个指针样的东西,
来处理各级菜单,如果提供的接口不一样,就很难用这个
指针了。