# -*- encoding: utf-8 -*-
import collections
'''
第28條: 繼承collections.abc以實現自定義的容器類型
關鍵:
1 下標訪問元素
原理: 假設bar是一個列表,將bar[0]轉換爲
bar.__getitem__(0)
所以當自己實現__getitem__方法,就可以使類的行爲表現得和序列一樣
要向使內置的len函數正常,需要實現__len__方法
2 collections.abc
作用: 定義了抽象基類,提供每種容器類型具備的常用方法
子類如果忘記實現某個方法,就會報錯
3 總結
如果定製子類簡單,可以繼承python的容器類型
如果比較複雜,可以從collections.abc模塊的抽象基類中繼承
參考:
Effectiv Python 編寫高質量Python代碼的59個有效方法
'''
class BinaryNode(object):
def __init__(self, value, left=None, right=None):
self.value = value
self.left = left
self.right = right
class IndexableNode(BinaryNode):
def _search(self, count, index):
# return (found, count)
pass
def __getitem__(self, index):
found, _ = self._search(0, index)
if not found:
raise IndexError('Index out of range')
return found.value
class SequenceNode(IndexableNode):
def __len__(self):
_, count = self._search(0, None)
return count
def getTree():
tree = IndexableNode(
10,
left=IndexableNode(
5,
left=IndexableNode(2),
right=IndexableNode(6, right=IndexableNode(7))),
right=IndexableNode(
15,
left=IndexableNode(11)
)
)
return tree
# class BadType(collections.abc)
def process():
tree = getTree()
print 'LRR={value}'.format(
value=tree.left.right.right.value
)
# print "Index 0 ={value}".format(
# value=tree[0]
# )
if __name__ == "__main__":
process()