卡牌类继承问题排查:子类无法获取父类属性
问题排查与修复
核心问题:错误的继承逻辑
Deck(牌组)和Game(游戏)不应该继承Card(单张牌)——牌组是多张牌的集合,游戏是使用牌组的逻辑,它们和单张牌是组合关系,而非继承关系。原代码的继承导致初始化时依赖未定义的父类属性,直接引发错误。
其他具体问题
- Card类的
whole参数冗余,单张牌的属性suit/value/color已足够描述它 - Deck的
build方法中,suits被错误定义为单个字符串的列表,且颜色未与花色绑定(方块、红桃是红色,梅花、黑桃是黑色) - Game的
draw_cards方法逻辑混乱:用range(self.suit)遍历字符串会报错,取值时混淆了suit/value/color的对应关系 - 子类初始化时调用
super()传递未初始化的self.suit等属性,直接触发AttributeError
修复后的完整代码
import random as rand class Card: def __init__(self, suit, value): self.suit = suit self.value = value # 根据花色自动推导颜色,无需手动传入 self.color = "Red" if suit in ["Diamonds", "Hearts"] else "Black" def __repr__(self): # 优化显示格式,更直观 value_names = {1: "A", 11: "J", 12: "Q", 13: "K"} display_value = value_names.get(self.value, str(self.value)) return f"{display_value} of {self.suit} ({self.color})" class Deck: def __init__(self): self.cards = [] self.build() # 初始化时自动构建牌组 def build(self): suits = ["Diamonds", "Clubs", "Hearts", "Spades"] values = list(range(1, 14)) # 1到13 # 生成所有52张牌的Card实例 self.cards = [Card(suit, value) for suit in suits for value in values] return self.cards def shuffle(self): # 添加洗牌方法,符合实际牌组逻辑 rand.shuffle(self.cards) return self.cards class Game: def __init__(self): self.deck = Deck() # 游戏持有一个牌组实例 self.deck.shuffle() # 初始化时洗牌 def draw_cards(self, count=1): # 从牌组顶部抽指定数量的牌 drawn = [] for _ in range(count): if self.deck.cards: drawn.append(self.deck.cards.pop()) else: drawn.append("牌组已空") return drawn # 测试示例 if __name__ == "__main__": game = Game() print("抽3张牌:") print(game.draw_cards(3))
关键改动说明
- 修正继承关系:Deck和Game不再继承Card,改为通过实例持有(Game包含Deck,Deck包含多个Card)
- 简化Card类:自动根据花色推导颜色,移除冗余的
whole参数,优化__repr__显示 - Deck类优化:正确生成52张Card实例,添加洗牌方法,符合真实牌组逻辑
- Game类重构:基于Deck实例实现抽牌逻辑,避免随机取值的混乱,支持抽多张牌
内容的提问来源于stack exchange,提问作者stang-Spitfire1975
相关产品推荐
相关产品推荐

