第047講 魔法方法 定製序列

2021-10-08 18:28:30 字數 4406 閱讀 1121

常言道:「無規矩不成方圓」,講的是萬事萬物的發展都要在一定的規則下去執行,只有遵循一定的協議去做,事情才能夠按照正確的道路去發展。我們今天要談的是 定製容器,想要成功的實現容器的定製,我們要先談一談協議,那麼什麼是協議呢?

協議(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 兩個方法。容器型別的魔法方法如下 編寫乙個不可改變的自定義列表,...