本章概述:python基础——面向对象练习
1、制作扑克
说明:一幅扑克有52张牌(除大小王),我们需要实现随机抽取扑克牌的功能。
使用面向对象编程方法,首先需要从问题的需求中找到对象并抽象出对应的类,此外还要找到对象的属性和行为。我们可以从需求的描述中找出名词和动词,名词通常就是对象或者是对象的属性,而动词通常是对象的行为。所以上面的说明至少有两个对象,分别为扑克和扑克牌,扑克有随机抽取的功能。一幅扑克有52张牌,扑克牌有两个属性,分别为大小跟花色,并且一幅扑克的每张牌都是这样,因此我们可以把定义一个扑克牌类,然后再定义扑克类,首先定义扑克牌类。
1 2 3 4 5 6 7 8 9 10 11
| class Card:
def __init__(self, rand, suit): self.rand = rand self.suit = suit
def __repr__(self): return f'{self.suit}{self.rand}'
card1 = Card('5', '黑桃') print(card1)
|
接下来定义扑克类
1 2 3 4 5 6 7 8 9
| import random class Poker: rands = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K'] suits = ['方块', '梅花', '红桃', '黑桃']
def __init__(self): self.__cards = [Card(rand, suit) for rand in self.rands for suit in self.suits]
|
实现扑克具体的行为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Poker: rands = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K'] suits = ['方块', '梅花', '红桃', '黑桃']
def __init__(self): self.__cards = [Card(rand, suit) for rand in self.rands for suit in self.suits]
def __len__(self): return len(self.__cards)
def get(self): return random.choice(self.__cards)
|
可以通过下面的代码来测试下Poker
类。
1 2 3
| poker=Poker() print(len(poker)) print(poker.get())
|
上面的代码只实现了扑克的两种行为,实际上如果想实现一些扑克游戏功能,则扑克还需要更多的行为,比如发牌行为、洗牌行为等等,扑克牌类比如还需要比较大小的行为。现在为扑克牌类新增一个比较大小的函数,但是我们需要比较的是两个对象的大小,而普通的比较运算符不能直接作用于Card类型,因此我们需要对运算符进行重载,这里我们只重载<符号,重载小于号用到的特殊方法是__lt__
,上一篇博客有提到一些特殊方法,可以去看一看。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class Card:
def __init__(self, rand, suit): self.rand = rand self.suit = suit
def __repr__(self):
return f'{self.suit}{self.rand}'
def __lt__(self, other): if Poker.rands.index(self.rand) == Poker.rands.index(other.rand): return Poker.suits.index(self.suit) < Poker.suits.index(other.suit)
return Poker.rands.index(self.rand) < Poker.rands.index(other.rand)
|
通过以下代码进行测试
1 2 3 4
| c1=Card('J','红桃') c2=Card('J','方块') print(c1<c2) print(poker.get()<poker.get())
|
实际上,重载了__lt__
方法后,实际上也可以实现大于号预算,同样的道理,如果想实现==或!=运算,只需要实现这两种特殊方法的一种即可,<=或>=也是如此。