【python】魔法方法 :__getitem__ 但金、 __len__韭山、__setitem__等的使用

在Python中,如果我們想實現(xiàn)創(chuàng)建類似于序列和映射的類(可以迭代以及通過[下標(biāo)]返回元素),可以通過重寫魔法方法__getitem__钱磅、__setitem__梦裂、__delitem__、__len__方法去模擬盖淡。

魔術(shù)方法的作用:

__getitem__(self,key):返回鍵對應(yīng)的值年柠。
__setitem__(self,key,value):設(shè)置給定鍵的值
__delitem__(self,key):刪除給定鍵對應(yīng)的元素。
__len__():返回元素的數(shù)量

【注釋】只要實現(xiàn)了__getitem____len__方法禁舷,就會被認(rèn)為是序列彪杉。

  • 可以用__len__():函數(shù)來查看對象長度
  • __getitem__(self,key): 可以對對象進(jìn)行[]操作,如切片牵咙,索引派近,iterd等高級操作。
  • 如果在類中定義了__getitem__()方法洁桌,那么他的實例對象(假設(shè)為P)就可以這樣P[key]取值渴丸。當(dāng)實例對象做P[key]運(yùn)算時,就會調(diào)用類中的__getitem__()方法另凌。

這些魔術(shù)方法的原理就是:當(dāng)我們對類的屬性item進(jìn)行下標(biāo)的操作時谱轨,首先會被__getitem__()、__setitem__()吠谢、__delitem__()攔截土童,從而執(zhí)行我們在方法中設(shè)定的操作,如賦值工坊,修改內(nèi)容献汗,刪除內(nèi)容等等。
這個方法應(yīng)該以與鍵相關(guān)聯(lián)的方式存儲值王污,以便之后能夠使用__setitem__來獲取罢吃。當(dāng)然,這個對象可變時才需要實現(xiàn)這個方法昭齐。

舉個栗子:
定義一副撲克牌(不包括大小王)尿招,對牌進(jìn)行洗牌,然后發(fā)牌阱驾。

mport collections
Card = collections.namedtuple('Card',['rank','suit'])
#也可以使用一個類來定義Card
# class Card:
#     def __init__(self,rank,suit):
#         self.rank = rank
#         self.suit = suit


class Puke:
    ranks = [str(n) for n in range(2,11) ] + list('JQKA')
    suits = "黑桃 方塊 梅花 紅心".split()

    def __init__(self):
        self._cards = [Card(rank,suit) for suit in self.suits for rank in self.ranks]

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

    def __getitem__(self, item):
        return self._cards[item]

    def __setitem__(self, key, value):
        print(key,value)
        self._cards[key] = value

pk = Puke()

# print(pk._cards)
# for card in pk:
    print(card)
print(pk[2:6])
print(pk[12::13])
pk[1:3] = [Card(rank='A',suit='紅桃')] * 3
print(pk[1:3])

Output:


[Card(rank='2', suit='黑桃'), Card(rank='3', suit='黑桃'), Card(rank='4', suit='黑桃'), Card(rank='5', suit='黑桃'), Card(rank='6', suit='黑桃'), Card(rank='7', suit='黑桃'), Card(rank='8', suit='黑桃'), Card(rank='9', suit='黑桃'), Card(rank='10', suit='黑桃'), Card(rank='J', suit='黑桃'), Card(rank='Q', suit='黑桃'), Card(rank='K', suit='黑桃'), Card(rank='A', suit='黑桃'), Card(rank='2', suit='方塊'), Card(rank='3', suit='方塊'), Card(rank='4', suit='方塊'), Card(rank='5', suit='方塊'), Card(rank='6', suit='方塊'), Card(rank='7', suit='方塊'), Card(rank='8', suit='方塊'), Card(rank='9', suit='方塊'), Card(rank='10', suit='方塊'), Card(rank='J', suit='方塊'), Card(rank='Q', suit='方塊'), Card(rank='K', suit='方塊'), Card(rank='A', suit='方塊'), Card(rank='2', suit='梅花'), Card(rank='3', suit='梅花'), Card(rank='4', suit='梅花'), Card(rank='5', suit='梅花'), Card(rank='6', suit='梅花'), Card(rank='7', suit='梅花'), Card(rank='8', suit='梅花'), Card(rank='9', suit='梅花'), Card(rank='10', suit='梅花'), Card(rank='J', suit='梅花'), Card(rank='Q', suit='梅花'), Card(rank='K', suit='梅花'), Card(rank='A', suit='梅花'), Card(rank='2', suit='紅心'), Card(rank='3', suit='紅心'), Card(rank='4', suit='紅心'), Card(rank='5', suit='紅心'), Card(rank='6', suit='紅心'), Card(rank='7', suit='紅心'), Card(rank='8', suit='紅心'), Card(rank='9', suit='紅心'), Card(rank='10', suit='紅心'), Card(rank='J', suit='紅心'), Card(rank='Q', suit='紅心'), Card(rank='K', suit='紅心'), Card(rank='A', suit='紅心')]
[Card(rank='4', suit='黑桃'), Card(rank='5', suit='黑桃'), Card(rank='6', suit='黑桃'), Card(rank='7', suit='黑桃')]
[Card(rank='A', suit='黑桃'), Card(rank='A', suit='方塊'), Card(rank='A', suit='梅花'), Card(rank='A', suit='紅心')]
slice(1, 3, None) [Card(rank='A', suit='紅桃'), Card(rank='A', suit='紅桃'), Card(rank='A', suit='紅桃')]
[Card(rank='A', suit='紅桃'), Card(rank='A', suit='紅桃')]

【注意】:我們會發(fā)現(xiàn)output中就谜,輸出了:slice(1, 3, None),下面給出解釋里覆。


切片原理

語法:

class slice(stop)
class slice(start, stop[, step])

參數(shù)說明:

  • start -- 起始位置
  • stop -- 結(jié)束位置
  • step -- 間距

slice() 函數(shù)實現(xiàn)切片對象丧荐,主要用在切片操作函數(shù)里的參數(shù)傳遞。

slice用于規(guī)定序列的選取規(guī)則

舉兩個栗子來看看:

step = slice(0,5,2)
components = [11, 22, 66, 88, 99, 00, 123]
print(components[step])

Output:

[11, 66, 99]

切片原理

class MySeq:
    def __getitem__(self, item):
        return item

s = MySeq()
print(s[1])
print(s[1:4])
print(s[1:4:2])
print(s[1:4:2,7:9])

output

1
slice(1, 4, None)
slice(1, 4, 2)
(slice(1, 4, 2), slice(7, 9, None))

(程序員必會的 hhhhh.....)
看看slice在python3.7中是怎么描述的:

help(slice)
Help on class slice in module builtins:

class slice(object)
 |  slice(stop)
 |  slice(start, stop[, step])
 |  
 |  Create a slice object.  This is used for extended slicing (e.g. a[0:10:2]).
 |  
 |  Methods defined here:

 |  有點長租谈。。。忽略  ********

 |  ----------------------------------------------------------------------
 |  Static methods defined here:
 |  
 |  __new__(*args, **kwargs) from builtins.type
 |      Create and return a new object.  See help(type) for accurate signature.
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |  
 |  start
 |  
 |  step
 |  
 |  stop
 |  
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |  
 |  __hash__ = None
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末割去,一起剝皮案震驚了整個濱河市窟却,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌呻逆,老刑警劉巖夸赫,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異咖城,居然都是意外死亡茬腿,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進(jìn)店門宜雀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來切平,“玉大人,你說我怎么就攤上這事辐董°财罚” “怎么了?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵简烘,是天一觀的道長苔严。 經(jīng)常有香客問我,道長孤澎,這世上最難降的妖魔是什么届氢? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮覆旭,結(jié)果婚禮上退子,老公的妹妹穿的比我還像新娘。我一直安慰自己姐扮,他們只是感情好絮供,可當(dāng)我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著茶敏,像睡著了一般壤靶。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上惊搏,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天贮乳,我揣著相機(jī)與錄音,去河邊找鬼恬惯。 笑死向拆,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的酪耳。 我是一名探鬼主播浓恳,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼刹缝,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了颈将?” 一聲冷哼從身側(cè)響起梢夯,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎晴圾,沒想到半個月后颂砸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡死姚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年人乓,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片都毒。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡色罚,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出温鸽,到底是詐尸還是另有隱情保屯,我是刑警寧澤,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布涤垫,位于F島的核電站姑尺,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蝠猬。R本人自食惡果不足惜切蟋,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望榆芦。 院中可真熱鬧柄粹,春花似錦、人聲如沸匆绣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽盅粪。三九已至咏删,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間拣凹,已是汗流浹背森爽。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留嚣镜,地道東北人爬迟。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像菊匿,于是被迫代替她去往敵國和親付呕。 傳聞我的和親對象是個殘疾皇子计福,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內(nèi)容