常言道:「無規矩不成方圓」,講的是萬事萬物的發展都要在一定的規則下去執行,只有遵循一定的協議去做,事情才能夠按照正確的道路去發展。我們今天要談的是 定製容器,想要成功的實現容器的定製,我們要先談一談協議,那麼什麼是協議呢?
協議(protlcols)與其他程式語言中的介面很相似,它規定你在哪些地方必須定義哪些東西。然而,在python中的協議就顯得不那麼正式了。事實上,python中的協議更像是一種指南,一種建議。例如,我們之前談到的鴨子型別(ducktyping):當看到乙隻鳥走起來像鴨子、游泳起來像鴨子、叫起來也像鴨子,那麼這只鳥就可以被稱為鴨子。
python就是這樣,它並不會嚴格要求你要怎樣去做,而是靠你自覺和經驗去把事情做得更好。
在python中,序列型別(例如:列表,元組,字串)或者對映型別(例如:字典)都是屬於容器型別,它們都是裡面存放各式各樣的物件。那麼這一節課我們就來談定製容器。我們需要知道的是有關定義容器的協議。這裡有兩種區分:
如果說你希望定製的容器是不可變的話(例如元組、字串),你只需要定義len() 和getitem() 方法。
如果說你希望定製的容器是可變的話,那麼除了 需要定義len() 和__getitem__() 方法之外,你還需要定義__setitem__() 和delitem() 兩個方法。
有關python魔法方法的講解如果忘了的,可以看一下->python魔法方法詳解。
引數是可變數量的 (*args),因為我們不知道使用者要傳入多少個資料,我們把使用者輸入的資料初始化為乙個列表,self.values就是乙個列表,我們通過列表推導式的形式把資料存放到 self.values
這個列表中。另外,還需要記錄列表中每個元素被訪問的次數,我們立刻會想到字典,我們把每個元素在列表中的下標作為字典的鍵,然後值就是累計的訪問次數。我們定義
self.count 這個字典,初始化可以使用 fromkeys
,並把所有下標對應的key所對應的值初始化為0。我們這是乙個不可變的容器,所以需要定義len() 和getitem()
方法,len() 就直接是返回 len(self.values) 的值,getitem() 中的 key
就是對應的下標,我們這裡是獲取key對應的值,所以需要返回self.values[key],另外,對應著訪問了它一次,所以對應的
self.count[key] 加1。
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]
答:應該定義reversed() 方法,提供對內建函式 reversed() 的支援。
答:在 python 中,我們通過 len() 內建函式來查詢容器的「容量」,所以容器應該定義len() 方法。l
答:讀 ——getitem(),寫 ——setitem(),刪除 ——delitem()
答:在 python 中,協議更像是一種指南。這有點像我們之前在課後作業中提到的「鴨子型別」 —— 當看到乙隻鳥走起來像鴨子、游泳起來像鴨子、叫起來也像鴨子,那麼這只鳥就可以被稱為鴨子。python就是這樣,並不會嚴格地要求你一定要怎樣去做,而是讓你靠著自覺和經驗把事情做好!
今天只有一道動動手的題目,但在寫**的時候要時刻考慮到你的列表增加了計數器功能,所以請務必要考慮周全再提交答案。
附課堂上的例子:
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]
**
class
countlist
(list):
def__init__
(self,
*args)
:super()
.__init__(args)
self.count =
for i in args:0)
def__len__
(self)
:return
len(self.count)
def__getitem__
(self, key)
: self.count[key]+=1
return
super()
.__getitem__(key)
def__setitem__
(self, key, value)
: self.count[key]+=1
super()
.__setitem__(key, value)
def__delitem__
(self, key)
:del self.count[key]
super()
.__delitem__(key)
defcounter
(self, key)
:return self.count[key]
def(self, value):0
)super()
defpop
(self, key=-1
):del self.count[key]
return
super()
.pop(key)
defremove
(self, value)
: key =
super()
.index(value)
del self.count[key]
super()
.remove(value)
definsert
(self, key, value)
: self.count.insert(key,0)
super()
.insert(key, value)
defclear
(self)
: self.count.clear(
)super()
.clear(
)def
reverse
(self)
: self.count.reverse(
)super()
.reverse(
)
這裡繼承了list,原有乙個list屬性並新增了屬性count,所以每個函式只需要對list本身進行修改(通過super呼叫魔法方法)修改本身的list屬性同時對count進行相應修改即可
魔法方法 定製序列(有關Protocol協議)
讀書筆記 重打 class countlist list def init self,args super.init args self count for i in args def len self return len self.count def getitem self,key self....
Python3 魔法方法 定製序列
分別是 列表 元組 字串 python中的協議更像是一種指南,例如鴨子型別,乙隻鳥像鴨子一樣走,像鴨子一樣叫,像鴨子一樣遊然後這只鳥就可以叫做鴨子 如果希望定製的容器是不可變的,那麼只需要定義 len 和 getitem 方法 如果希望定製的容器是可變的,那麼還需要定義 setitem 和 deli...
python 魔法方法 定製序列 迭代器
容器型別的協議 如果說你希望定製的容器是不可變的話,你只需要定義 len 和 getitem 方法。如元組 字串 如果你希望定製的容器是可變的話,除了 len 和 getitem 方法,你還需要定義 setitem 和 delitem 兩個方法。容器型別的魔法方法如下 編寫乙個不可改變的自定義列表,...