序列型別協議結構,你懂了嗎?
阿新 • • 發佈:2018-12-17
序列型別的協議
- 序列抽象基類的資料結構 都在 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
- 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 除了具有它繼承的特性外,它又新加了一些特性 如 setitem,delitem,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