自訂容器(Container)
經(jīng)過之前編章的介紹,我們知道在 Python 中,常見的容器類型有: dict, tuple, list, string。其中也提到可容器和不可變?nèi)萜鞯母拍?。其?tuple, string 是不可變?nèi)萜?,dict, list 是可變?nèi)萜???勺內(nèi)萜骱筒豢勺內(nèi)萜鞯牟顒e在於,不可變?nèi)萜饕坏┵x值後,就無法對其中的某個元素進行修改。當然具體的介紹,可以看回之前的文章,有圖文介紹。
那麼這裡先提出一個問題,這些資料結(jié)構(gòu)就夠我們開發(fā)使用嗎?不夠的時候,或者說有些特殊的需求不能單單只用這些基本的容器解決的時候,該怎麼辦呢?
這時候就需要自訂容器了,那麼具體我們該怎麼做呢?
功能 | 說明 |
#自訂不可變?nèi)萜黝愋?/td> | 需要定義_ _len__ 和__getitem__ 方法 |
自訂可變類型容器 | 在不可變?nèi)萜黝愋偷幕A上增加定義__setitem__ 和__delitem__ |
#自訂的資料型別需要迭代 | 需定義__iter__ |
#傳回自訂容器的長度 | 需實作_ _len__(self) |
自訂容器可以呼叫self[key] ,如果key 類型錯誤,拋出TypeError ,如果沒法返回key對應的數(shù)值時,該方法應該拋出ValueError? | 需要實作__getitem__(self, key) |
當執(zhí)行self[key] = value 時 | #呼叫是__setitem__(self, key, value)這個方法 |
當執(zhí)行del self[key] 方法 | 其實呼叫的方法是__delitem__(self, key) |
當你想你的容器可以執(zhí)行for x in container: 或使用iter(container) 時 | 需要實作__iter__(self) ,該方法傳回的是一個迭代器 |
來看一下使用上面魔術(shù)方法實作Haskell 語言中的一個資料結(jié)構(gòu):
#!/usr/bin/env python3 # -*- coding: UTF-8 -*- class FunctionalList: ''' 實現(xiàn)了內(nèi)置類型list的功能,并豐富了一些其他方法: head, tail, init, last, drop, take''' def __init__(self, values=None): if values is None: self.values = [] else: self.values = values def __len__(self): return len(self.values) def __getitem__(self, key): return self.values[key] def __setitem__(self, key, value): self.values[key] = value def __delitem__(self, key): del self.values[key] def __iter__(self): return iter(self.values) def __reversed__(self): return FunctionalList(reversed(self.values)) def append(self, value): self.values.append(value) def head(self): # 獲取第一個元素 return self.values[0] def tail(self): # 獲取第一個元素之后的所有元素 return self.values[1:] def init(self): # 獲取最后一個元素之前的所有元素 return self.values[:-1] def last(self): # 獲取最后一個元素 return self.values[-1] def drop(self, n): # 獲取所有元素,除了前N個 return self.values[n:] def take(self, n): # 獲取前N個元素 return self.values[:n]