__len__:返回對象的長度html
__getitem__:得到某一項的值dom
__setitem__:設置莫一項的值測試
__delitem__刪除某一項spa
__contains__:包含某一項htm
實現說明:對象
1) 模擬一副撲克牌,包含兩個類,一個是卡片類(Card),一個是 撲克(PuKe),PuKe類包含52張牌,13個大小(AJQK,2-10),4張花色("redheart", "spades", "diamond", "club").blog
2) 卡片類包含兩個屬性,rank(等級)、color(花色),以及重寫了__eq__方法,判斷卡片的相同性,爲後續PuKe類中的__getitem__,__setitem__方法中的判斷作鋪墊;索引
3) 實現PuKe中的__len__,__getitem__,__setitem__,__contains__等方法。ip
代碼實現:get
Card類代碼以下:
class Card: def __init__(self, rank, color): self.rank = rank self.color = color def __repr__(self): return "Card rank is %s and color is %s" % (self.rank, self.color) def __eq__(self, other): if isinstance(other, (tuple, )): if self.rank == other[0] and self.color == other[1]: return True if isinstance(other, (Card,)): if self.rank == other.rank and self.color == other.color: return True return False
說明:
1) __init__方法包含兩個屬性,rank和color
2) 重寫__repr__方法,格式化後續的Card類對象的打印信息
3) 重寫__eq__方法,只有rank、color兩個屬性都知足的狀況下,才能判斷卡片是相同的。
PuKe類的實現:
class PuKe: ranks = [str(rank) for rank in range(2, 11)] + list("JQKA") colors = ["redheart", "spades", "diamond", "club"] def __init__(self): """ 初始化生成牌 """ self._cards = [Card(rank, color) for rank in PuKe.ranks for color in PuKe.colors] def __len__(self): """ 返回一副撲克中牌的張數 :return: """ return len(self._cards) def __getitem__(self, item): """ 得到某一張牌 :param item: :return: """ assert item is not None result = None if isinstance(item, (int,)): result = self._cards[item] elif isinstance(item, (tuple,)): result = [] for card in self._cards: if card == item: return card return result def __setitem__(self, key, value): """ 設置某一項的值 :param key: rank+color,爲一元組 :param value: other rank+color,元組 :return: void """ assert key is not None if not isinstance(key, (tuple,)) or not isinstance(value, (tuple,)): return for card in self._cards: if card == key: card.rank = value[0] card.color = value[1] return def __contains__(self, item): """ 判斷是否包含一個牌 :param item: 元組 :return: """ for card in self._cards: if card == item: return True return False
說明:
1) __init__方法,初始化52中卡片
2) __len__方法,返回卡片的數量,確定等於52
3) 在__getitem__方法的實現中,兩種實現方法來得到某一張卡片,一個是根據索引號,一個是根據卡片的rank和color屬性來定位一張卡片。
4) __setitem__方法中,key是rank和color的元組,實現卡片的定位
5) __contains__方法,判斷卡片是否在撲克牌中。
代碼測試:
if __name__ == '__main__': puke1 = PuKe() print("一副牌的張數爲%d " % len(puke1)) print("牌分別爲:") #循環,一樣會調用__getitem__ for card in puke1: print(card) card5 = puke1[5] print("第5張牌的rank爲%s,花色爲:%s" % (card5.rank, card5.color)) cardA = puke1[("A", "spades")] print("A牌的花色分別爲:%s" % cardA.color) print("隨機選張牌") from random import choice # 隨機選擇,一樣會調用__getitem__ card = choice(puke1) print(card) #會調用__setitem__方法 puke1[("7", "spades")] = ("7", "gagagwer") #再次打印puke for card in puke1: print(card) #會調用__container__方法 print(("7", "gagagwer") in puke1)
總結:循環會調用__getitem__,若是某個對象要能循環,必須具有___getitem__方法