課時47:魔法方法:定製序列

那是個好男孩發表於2018-08-26

目錄:
  一、定製序列

  二、課時47課後習題及答案

 

****************

一、定製序列

****************

本節要談的是定製容器,要想成功的實現容器的定製,便需要先談一談協議。協議是什麼?

協議(Protocols)與其他程式語言中的介面很相似,它規定你哪些方法必須要定義。然而,在Python中的協議就顯得不那麼正式。事實上,在Python中,協議更像是一種指南。

這有點像Python極力推崇的鴨子型別【擴充套件閱讀】鴨子型別(duck typing)

在Python中,像序列型別(如列表、元組、字串)或對映型別(如字典)都是屬於容器型別。本節來講定製容器,那就必須先知道,定製容器有關的一些協議。

  • 如果說你希望定製的容器是不可變的話,你只需要定義__len__()和__getitem__()方法。
  • 如果你希望定製的容器是可變的話,除了__len__()和__getitem__()方法,你還需要定義__setitem__()和__delitem__()兩個方法。

下表列舉了定製容器型別相關的魔法方法及定義。

__len__(self)                      定義當被 len() 呼叫時的行為(返回容器中元素的個數)
__getitem__(self, key)                 定義獲取容器中指定元素的行為,相當於 self[key]
__setitem__(self, key, value)          定義設定容器中指定元素的行為,相當於 self[key] = value
__delitem__(self, key)                 定義刪除容器中指定元素的行為,相當於 del self[key]
__iter__(self)                         定義當迭代容器中的元素的行為
__reversed__(self)                     定義當被 reversed() 呼叫時的行為
__contains__(self, item)               定義當使用成員測試運算子(innot in)時的行為

舉個例子:編寫一個不可改變的自定義列表,要求記錄列表中每個元素被訪問的次數。

class CountList:
    def __init__(self, *args):
        self.values = [x for x in args]
        self.count = {}.fromkeys(range(len(self.values)), 0)
        #這裡使用列表的下標作為字典的鍵,注意不能用元素作為字典的鍵
        #因為列表的不同下標可能有值一樣的元素,但字典不能有兩個相同的鍵

    def __len__(self):
        return len(self.values)

    def __getitem__(self, key):
        self.count[key] += 1
        return self.values[key]
>>> c1 = CountList(1,3,5,7,9)
>>> c2 = CountList(2,4,6,8,10)
>>> c1[1]
3
>>> c2[1]
4
>>> c1[1] + c2[1]
7
>>> c1.count
{0: 0, 1: 2, 2: 0, 3: 0, 4: 0}
>>> c2.count
{0: 0, 1: 2, 2: 0, 3: 0, 4: 0}

 

*******************************

二、課時47課後習題及答案

*******************************

 

 

相關文章