classDeck: """一副扑克牌 —— 只需 __len__ 和 __getitem__""" ranks = [str(n) for n inrange(2, 11)] + list('JQKA') suits = '♠♥♦♣' def__init__(self): self._cards = [ (rank, suit) for suit in self.suits for rank in self.ranks ] def__len__(self): returnlen(self._cards) def__getitem__(self, position): return self._cards[position]
# 两个方法,解锁一系列操作 deck = Deck() print(len(deck)) # 52 print(deck[0]) # ('2', '♠') —— 索引 print(deck[-1]) # ('A', '♣') —— 负索引 print(deck[:5]) # 前5张牌 —— 切片 for card in deck: # for 循环 pass print(('2', '♠') in deck) # True —— in 运算符 print(list(reversed(deck))[:3]) # 反向 —— reversed()
自动支持的操作清单
实现 __len__ 和 __getitem__ 后,Python 自动给你:
操作
方法
示例
len()
__len__
len(deck)
索引
__getitem__
deck[0]
切片
__getitem__
deck[:5]
迭代
__getitem__
for card in deck
in 运算符
__contains__ 或迭代
('A','♠') in deck
reversed()
__reversed__ 或 __len__+__getitem__
reversed(deck)
随机选择
__len__
random.choice(deck)
排序
__getitem__+__len__
sorted(deck)
排序的坑
1 2 3 4 5 6 7 8 9 10 11 12 13 14
deck = Deck()
# 排序会报错,因为元组比较规则不适合牌面 # sorted(deck) # TypeError: '<' not supported
# 自定义排序键 defcard_key(card): rank_order = {r: i for i, r inenumerate(Deck.ranks)} suit_order = {s: i for i, s inenumerate(Deck.suits)} return (rank_order[card[0]], suit_order[card[1]])