一摞python風格的撲克牌

引子:本例子來自《流暢的Python》第1章中的一摞python風格的撲克牌。該示例是為了展示magic method (特殊方法)中的__getitem__函數實現後,具有多麼神奇的功能。


一摞python風格的撲克牌


代碼如下

<code>import collections
from random import choice

'''
collections.nametuple是用來實現對於只有少量屬性而沒有方法的類
'''
Card = collections.namedtuple('Card', ['rank', 'suite'])


class FrenchDeck:
'''
生成一幅撲克牌,通過實現兩個特殊函數__len__ 和 __getitem__, 使該類具有以下功能:
1.迭代
2.切片
3. in
4.排序
5. random.choice
6.長度

>>> card = Card('7', 'diamonds')
>>> print(card)
Card(rank='7', suite='diamonds')
>>> deck = FrenchDeck()
>>> print(len(deck))
52

>>> print(deck[0])
Card(rank='2', suite='spades')
>>> print(deck[-1])
Card(rank='A', suite='hearts')

# choice 使用
print(choice(deck))
>>> print(deck[:2])
[Card(rank='2', suite='spades'), Card(rank='2', suite='diamonds')]

>>> for card in deck: # doctest: +ELLIPSIS

... print(card)
Card(rank='2', suite='spades')
Card(rank='2', suite='diamonds')
Card(rank='2', suite='clubs')
...

>>> for card in reversed(deck): # doctest: +ELLIPSIS
... print(card)
Card(rank='A', suite='hearts')
Card(rank='A', suite='clubs')
Card(rank='A', suite='diamonds')
Card(rank='A', suite='spades')
...

>>> print(card in deck)
True
>>> suit_values = dict(spades=3, diamonds=2, clubs=1, hearts=0)
>>> def spades_high(card):
... rank_index = deck.ranks.index(card.rank)
... return rank_index * len(suit_values) + suit_values[card.suite]

>>> for card in sorted(deck, key=spades_high): # doctest: +ELLIPSIS
... print(card)
Card(rank='2', suite='hearts')
Card(rank='2', suite='clubs')
Card(rank='2', suite='diamonds')
...
'''
ranks = [str(n) for n in range(2, 11)] + list('JQKA')
suits = 'spades diamonds clubs hearts'.split()

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

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

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


if __name__ == '__main__':
import doctest
doctest.testmod(verbose=True)
/<code>

上面示例的知識點有:

  1. Card類的定義,使用的collections.namtuple函數定義的,它的作用就是針對有屬性但是沒有方法的類的聲明。
  2. FrenchDeck類,類中除了構造函數外,就僅實現了__len__ 和__getitem__函數,但是該類具有的功能卻是令人瞠目。包括:迭代,切片,求長度,in 判斷,random.choice,排序等功能。這個類很充分體現了python中序列的特性
  3. doctest測試。本例子測試是使用doctest實現的,之前有過一篇文章專門介紹doctest測試,本例子中的+ ELLIPSIS是為了輸出結果中太長,而使用的 ...的情況。


分享到:


相關文章: