自訂容器(Container)LOGIN

自訂容器(Container)

經過之前編章的介紹,我們知道在 Python 中,常見的容器類型有: dict, tuple, list, string。其中也提到可容器和不可變容器的概念。其中 tuple, string 是不可變容器,dict, list 是可變容器。可變容器和不可變容器的差別在於,不可變容器一旦賦值後,就無法對其中的某個元素進行修改。當然具體的介紹,可以看回之前的文章,有圖文介紹。

那麼這裡先提出一個問題,這些資料結構就夠我們開發使用嗎?不夠的時候,或者說有些特殊的需求不能單單只用這些基本的容器解決的時候,該怎麼辦呢?

這時候就需要自訂容器了,那麼具體我們該怎麼做呢?

功能說明
#自訂不可變容器類型需要定義_ _len__ 和__getitem__ 方法
自訂可變類型容器在不可變容器類型的基礎上增加定義__setitem__ 和__delitem__
#自訂的資料型別需要迭代需定義__iter__
#傳回自訂容器的長度需實作_ _len__(self)
自訂容器可以呼叫self[key] ,如果key 類型錯誤,拋出TypeError ,如果沒法返回key對應的數值時,該方法應該拋出ValueError 需要實作__getitem__(self, key)
當執行self[key] = value 時#呼叫是__setitem__(self, key, value)這個方法
當執行del self[key] 方法其實呼叫的方法是__delitem__(self, key)
當你想你的容器可以執行for x in container: 或使用iter(container) 時需要實作__iter__(self) ,該方法傳回的是一個迭代器

來看一下使用上面魔術方法實作Haskell 語言中的一個資料結構:

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
class FunctionalList:
    ''' 实现了内置类型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]


下一節
章節課件