"""
組合模式缕题,將對象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu)朗儒,組合模式使得用戶對單個對象和組合對象的使用具有一致性查坪。"""
"""
一個類定義的組合對象肪跋,它可以用名稱來存儲分層使用的字典歧蒋。
這個類是相同的分層字典,但它按名稱提供方法來添加/訪問/修改子元素州既,就像一個組合谜洽。
"""
def?normalize(val):
????"""?正常化一個特殊字符的字符串吴叶,以便它可以被用來作為一個Python對象一個屬性
????"""
????if?val.find('-')?!=?-1:
????????val?=?val.replace('-',?'_')
????return?val
def?denormalize(val):
????"""?非規(guī)范化一個字符串"""
????if?val.find('_')?!=?-1:
????????val?=?val.replace('_',?'-')
????return?val
class?SpecialDict(dict):
????"""
????字典類褥琐,允許其鍵直接訪問屬性
????"""
????def?__getattr__(self,?name):
????????if?name?in?self.__dict__:
????????????return?self.__dict__[name]
????????elif?name?in?self:
????????????return?self.get(name)
????????else:
????????????#?檢查非規(guī)范化的名字
????????????name?=?denormalize(name)
????????????if?name?in?self:
????????????????return?self.get(name)
????????????else:
????????????????raise?AttributeError('沒有屬性名稱?%s'?%?name)
????def?__setattr__(self,?name,?value):
????????if?name?in?self.__dict__:
????????????self.__dict__[name]?=?value
????????elif?name?in?self:
????????????self[name]?=?value
????????else:
????????????#?檢查非規(guī)范化的名字
????????????name2?=?denormalize(name)
????????????if?name2?in?self:
????????????????self[name2]?=?value
????????????else:
????????????????#?新屬性
????????????????self[name]?=?value
class?CompositeDict(SpecialDict):
????"""一類像一個層次詞典。
????這個類是基于組合設(shè)計模式"""
????ID?=?0
????def?__init__(self,?name=''):
????????if?name:
????????????self._name?=?name
????????else:
????????????self._name?=?''.join(('id#',?str(self.__class__.ID)))
????????????self.__class__.ID?+=?1
????????self._children?=?[]
????????#?鏈接到父親
????????self._father?=?None
????????self[self._name]?=?SpecialDict()
????def?__getattr__(self,?name):
????????if?name?in?self.__dict__:
????????????return?self.__dict__[name]
????????elif?name?in?self:
????????????return?self.get(name)
????????else:
????????????#??檢查非規(guī)范化的名字
????????????name?=?denormalize(name)
????????????if?name?in?self:
????????????????return?self.get(name)
????????????else:
????????????????#查看孩子列表
????????????????child?=?self.findChild(name)
????????????????if?child:
????????????????????return?child
????????????????else:
????????????????????attr?=?getattr(self[self._name],?name)
????????????????????if?attr:
????????????????????????return?attr
????????????????????raise?AttributeError('no?attribute?named?%s'?%?name)
????def?isRoot(self):
????????"""?Return?我是否根組件"""
????????#?如果我沒有父母晤郑,我的根節(jié)點(diǎn)
????????return?not?self._father
????def?isLeaf(self):
????????"""?Return?葉節(jié)點(diǎn)?"""
????????#?我是一片葉節(jié)點(diǎn)敌呈,如果我沒有孩子
????????return?not?self._children
????def?getName(self):
????????"""?返回ConfigInfo對象的名稱?"""
????????return?self._name
????def?getIndex(self,?child):
????????"""返回孩子ConfigInfo對象的'child'的索引"""
????????if?child?in?self._children:
????????????return?self._children.index(child)
????????else:
????????????return?-1
????def?getDict(self):
????????"""?返回包含的詞典"""
????????return?self[self._name]
????def?getProperty(self,?child,?key):
????????"""?返回屬性值"""
????????#?首先get孩子的字典
????????childDict?=?self.getInfoDict(child)
????????if?childDict:
????????????return?childDict.get(key,?None)
????def?setProperty(self,?child,?key,?value):
????????"""
????????設(shè)置屬性的“key”的值
????????"""
????????#首先get孩子的字典
????????childDict?=?self.getInfoDict(child)
????????if?childDict:
????????????childDict[key]?=?value
????def?getChildren(self):
????????"""?返回此對象的直接子列表?"""
????????return?self._children
????def?getAllChildren(self):
????????"""?返回此對象的所有子列表?"""
????????l?=?[]
????????for?child?in?self._children:
????????????l.append(child)
????????????l.extend(child.getAllChildren())
????????return?l
????def?getChild(self,?name):
????????"""
?????????用給定名稱返回直接子對象
????????"""
????????for?child?in?self._children:
????????????if?child.getName()?==?name:
????????????????return?child
????def?findChild(self,?name):
????????"""
????????????從樹返回(用給定的名稱)子對象
????????"""
????????#?這將返回給定名稱的第一個子對象
????????#任何其他具有類似名稱的子對象不被考慮
????????for?child?in?self.getAllChildren():
????????????if?child.getName()?==?name:
????????????????return?child
????def?findChildren(self,?name):
????????"""?從樹返回給定名稱的子對象列表"""
????????#這將返回給定名稱的所有子項的列表贸宏,不論查詢的深度
????????children?=?[]
????????for?child?in?self.getAllChildren():
????????????if?child.getName()?==?name:
????????????????children.append(child)
????????return?children
????def?getPropertyDict(self):
????????"""?返回屬性字典"""
????????d?=?self.getChild('__properties')
????????if?d:
????????????return?d.getDict()
????????else:
????????????return?{}
????def?getParent(self):
????????return?self._father
????def?__setChildDict(self,?child):
????????"""
????????私有方法來設(shè)置子對象的'child'的字典在內(nèi)部字典
????????"""
????????d?=?self[self._name]
????????d[child.getName()]?=?child.getDict()
????def?setParent(self,?father):
????????self._father?=?father
????def?setName(self,?name):
????????"""
????????????設(shè)置此ConfigInfo對象的名稱為'name'
????????"""
????????self._name?=?name
????def?setDict(self,?d):
????????self[self._name]?=?d.copy()
????def?setAttribute(self,?name,?value):
????????self[self._name][name]?=?value
????def?getAttribute(self,?name):
????????return?self[self._name][name]
????def?addChild(self,?name,?force=False):
????????"""
????????添加一個新的子節(jié)點(diǎn)
????????如果可選標(biāo)志“force”設(shè)置為True,子對象被覆蓋磕洪,如果它已經(jīng)存在吭练。
????????該函數(shù)返回子對象,無論是新的或現(xiàn)有的
????????"""
????????if?type(name)?!=?str:
????????????raise?ValueError('Argument?should?be?a?string!')
????????child?=?self.getChild(name)
????????if?child:
????????????#?print('Child?%s?present!'?%?name)
????????????#?如果force==True?更換它
????????????if?force:
????????????????index?=?self.getIndex(child)
????????????????if?index?!=?-1:
????????????????????child?=?self.__class__(name)
????????????????????self._children[index]?=?child
????????????????????child.setParent(self)
????????????????????self.__setChildDict(child)
????????????return?child
????????else:
????????????child?=?self.__class__(name)
????????????child.setParent(self)
????????????self._children.append(child)
????????????self.__setChildDict(child)
????????????return?child
????def?addChild2(self,?child):
????????"""
????????添加子對象'child'析显。如果它已經(jīng)存在鲫咽,它由缺省覆蓋
????????"""
????????currChild?=?self.getChild(child.getName())
????????if?currChild:
????????????index?=?self.getIndex(currChild)
????????????if?index?!=?-1:
????????????????self._children[index]?=?child
????????????????child.setParent(self)
????????????????#?未設(shè)置現(xiàn)有的子節(jié)點(diǎn)的父級
????????????????currChild.setParent(None)
????????????????del?currChild
????????????????self.__setChildDict(child)
????????else:
????????????child.setParent(self)
????????????self._children.append(child)
????????????self.__setChildDict(child)
if?__name__?==?"__main__":
????window?=?CompositeDict('Window')
????frame?=?window.addChild('Frame')
????tfield?=?frame.addChild('Text?Field')
????tfield.setAttribute('size',?'20')
????btn?=?frame.addChild('Button1')
????btn.setAttribute('label',?'提交')
????btn?=?frame.addChild('Button2')
????btn.setAttribute('label',?'瀏覽')
????#print(window)
????#print(window.Frame)
????#print(window.Frame.Button1)
????#print(window.Frame.Button2)
????print(window.Frame.Button1.label)
????print(window.Frame.Button2.label)