2011年8月29日 星期一

[python]自己寫一個dict

當寫程式到後來,一定會想要自己寫一個物件來用。
而且,希望能跟 build-in 的物件一樣的使用。
舉例來說,我們想要一個 ordered dict,在 iteration 的時候,
能按照我們加進去的順序列出。

這個 dict 據說在 python 3 已經有了,
這裡只是練習一下該怎麼寫這一類的物件。
這方面的資料在官方文件的
The Python Language Reference >> 3. Data model

首先,要能夠使用 a[‘1a’] = “a” 這個語法,
物件要提供 def __setitem__(self,key,value)。
要能夠使用 b = a[‘1a’] 這個語法,
物件要提供 def __getitem__(self,key)
按照文件及我的需求(也就是要像一個 dict),
該物件要提供以下的 method,我完整的列出來
a = orderdict()

def has_key(self,key): 仿 dict 的 has_key
__setitem__(self,key,value): 提供 a[‘1a’] = “a”
__getitem__(self,key) 提供 b = a[‘1a’]
def __len__(self): 提供 len(a)
def __iter__(self): 提供 for i in a:
def __contains__(self,item): 依照文件,提供這個method,可以提高 in 這個 operation 的效率。參見3.4.5
def __repr__(self): 自定被 print 呼叫時的文字表達

完整的物件長像:

class orderdict():
    def __init__(self):
        self.list = []
        self.dict = {}
    def has_key(self,key):
        return self.dict.has_key(key)
    def __setitem__(self,key,value):
        if self.dict.has_key(key):
            self.dict[key] = value
        else:
            self.list.append(key)
            self.dict[key] = value
    def __getitem__(self,key):
        if self.has_key(key):
            return self.dict[key]
        else:
            raise KeyError
    def __delitem__(self, key):
        if self.has_key(key):
            del self.dict[key]
            self.list.remove(key)
    def __len__(self):
        return len(self.dict)
    def __iter__(self):
        return self.list.__iter__()
    def __contains__(self,item):
        return self.dict.has_key(item)
    def __repr__(self):
        return str(a.dict)

這樣子就有看來不錯的物件可以用了。
以後要寫物件自己用,一定要參考 The Python Language Reference >> 3. Data model
才會有好用的物件。

沒有留言:

張貼留言