1. 程式人生 > >序列型別協議結構,你懂了嗎?

序列型別協議結構,你懂了嗎?

序列型別的協議

  1. 序列抽象基類的資料結構 都在 from collections import abc 這個模組,我們開啟 from _collections_abc import all,在abc 模組裡面可以看到內容如下 :
__all__ = ["Awaitable", "Coroutine",
           "AsyncIterable", "AsyncIterator", "AsyncGenerator",
           "Hashable", "Iterable", "Iterator", "Generator", "Reversible",
           "Sized", "Container", "Callable", "Collection",
           "Set", "MutableSet",
           "Mapping", "MutableMapping",
           "MappingView", "KeysView", "ItemsView", "ValuesView",
           "Sequence", "MutableSequence",
           "ByteString",
           ]

可以看到 上邊的列表列出來都是 collection 抽象基類. 咱們只需要關注 兩個 “Sequence”, “MutableSequence”, Sequence 是不可變序列型別,MutableSequence 是可變序列型別.這些抽象型別有利於我們理解資料結構以及他們的協議是什麼樣的.

2. Sequence

1. Sequence 繼承的類

class Sequence(Reversible, Collection):    #繼承了兩個類 Reversible, Collection

 @abstractmethod            # 抽象方法的標識, 如果用他必須重寫這個方法
    

其中 Reversible 是序列的翻轉,例如ABC 變成CBA, Collection 我們繼續開啟這個檔案如下 :

class Collection(Sized, Iterable, Container):   
  #又繼承了這三個,Sized 大家都知道里面有個魔法喊len,可以計算序列的長度,Iterable是個迭代器又了他可以記性for迴圈,
  #Container   他方法裡有 __contains__ 魔法函式 有了它 ,我們就可以用 in 這個欄位, 例如 if i  in  list()   

    __slots__ = ()

    @classmethod
    def __subclasshook__(cls, C):
        if cls is Collection:
            return _check_methods(C,  "__len__", "__iter__", "__contains__")
        return NotImplemented
  1. Sequence 的魔法函式構成了序列的協議. 魔法函式不單指Sequence 自身抽象方法和魔法函式還包括他自己繼承類裡面的. 開啟Sequence 類檢視方法如下:
@abstractmethod 
def __getitem__(self, index):     #這個前面已經講過,可以把類物件變成 序列物件.
        raise IndexError

    def __iter__(self):    # 迭代器 有了它,可以用for 迴圈.
        i = 0
        try:
            while True:
                v = self[i]
                yield v
                i += 1
        except IndexError:
            return

    def __contains__(self, value):       #  可以用 in 方法 判斷是否在容器裡面 
        for v in self:
            if v is value or v == value:
                return True
        return False

    def __reversed__(self):          #序列的翻轉
        for i in reversed(range(len(self))):
            yield self[i]

3.MutableSequence 是可變的序列 開啟檔案後可以看到這個類 , 他是繼承 了Sequence 除了具有它繼承的特性外,它又新加了一些特性 如 setitemdelitem,insert, append,clear, reverse,extend,pop,remove,iadd. 這些都是可變序列的特性.

class MutableSequence(Sequence):

    __slots__ = ()

    """All the operations on a read-write sequence.

    Concrete subclasses must provide __new__ or __init__,
    __getitem__, __setitem__, __delitem__, __len__, and insert().     #說明 提示要實現這些方法.

    """

    @abstractmethod                                   #必須實現的方法 
    def __setitem__(self, index, value):
        raise IndexError
  
    @abstractmethod                         #必須實現的方法 
    def __delitem__(self, index):
        raise IndexError

    @abstractmethod         #必須實現的方法 
    def insert(self, index, value):
        'S.insert(index, value) -- insert value before index'
        raise IndexError

    def append(self, value):
        'S.append(value) -- append value to the end of the sequence'
        self.insert(len(self), value)

    def clear(self):
        'S.clear() -> None -- remove all items from S'
        try:
            while True:
                self.pop()
        except IndexError:
            pass

    def reverse(self):
        'S.reverse() -- reverse *IN PLACE*'
        n = len(self)
        for i in range(n//2):
            self[i], self[n-i-1] = self[n-i-1], self[i]

    def extend(self, values):
        'S.extend(iterable) -- extend sequence by appending elements from the iterable'
        for v in values:
            self.append(v)

    def pop(self, index=-1):
        '''S.pop([index]) -> item -- remove and return item at index (default last).
           Raise IndexError if list is empty or index is out of range.
        '''
        v = self[index]
        del self[index]
        return v

    def remove(self, value):
        '''S.remove(value) -- remove first occurrence of value.
           Raise ValueError if the value is not present.
        '''
        del self[self.index(value)]

    def __iadd__(self, values):
        self.extend(values)
        return self