Python在__init__中调用@classmethod实现扑克牌类的可行性咨询
问题解答
你构想的写法存在的问题
你写的这段带@classmethod的代码无法正常运行,原因有两个:
@classmethod接收的第一个参数cls是Deck类本身,不是你创建的Deck实例,你要操作的self.cards是实例的专属属性,类本身既没有这个属性,也没有append方法,执行到cls.append(card.name)会直接报错。- 你要在
__init__里调用的逻辑封装成普通实例方法就足够,完全不需要用@classmethod。
原实现的优化点
你原来的写法可以调整这几个地方,扩展性和实用性会更好:
- 不要把csv路径写死成全局变量,可以做成初始化参数,支持传入自定义牌表文件
- 建议
self.cards里直接存Card实例,而不是存card.name字符串,后续你要做洗牌、算点数、判断花色等操作时,可以直接取Card的suit、rank属性,不用再解析字符串 - 加载牌的逻辑可以封装成独立的实例方法,
__init__里直接调用即可,代码结构更清晰
优化后代码示例
版本1:用普通实例方法封装加载逻辑
import csv from cards import Card class Deck: def __init__(self, csv_path="C:/path/to/your/cards.csv"): self.cards = [] self.csv_path = csv_path # 初始化时直接调用加载牌组的方法 self.load_cards_from_csv() def load_cards_from_csv(self): """从csv文件加载牌组数据,生成Card实例存入cards列表""" with open(self.csv_path, "r", encoding="utf-8") as f: reader = csv.DictReader(f) for card_info in reader: new_card = Card( suit=card_info["suit"], rank=card_info["rank"] ) # 存Card实例,要打印的时候直接取new_card.name就行 self.cards.append(new_card)
如果你需要清空牌组重新加载,直接调用实例.load_cards_from_csv()就行,非常灵活。
版本2:如果你确实需要用@classmethod(适合多初始化方式的场景)
@classmethod的典型使用场景是做备用构造器,比如你既支持从csv加载牌组,也支持直接生成标准52张牌不需要读取文件,这时候可以这么写:
import csv from cards import Card class Deck: def __init__(self): self.cards = [] @classmethod def from_csv(cls, csv_path="C:/path/to/your/cards.csv"): """从csv文件生成Deck实例的类方法构造器""" deck_instance = cls() with open(csv_path, "r", encoding="utf-8") as f: reader = csv.DictReader(f) for card_info in reader: new_card = Card( suit=card_info["suit"], rank=card_info["rank"] ) deck_instance.cards.append(new_card) return deck_instance # 还可以加其他构造器,比如直接生成标准牌组 @classmethod def generate_standard_deck(cls): suits = ["Spades", "Hearts", "Diamonds", "Clubs"] ranks = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"] deck_instance = cls() for suit in suits: for rank in ranks: deck_instance.cards.append(Card(suit, rank)) return deck_instance
使用的时候直接调用类方法生成实例即可:
# 从csv加载牌组 deck1 = Deck.from_csv("your/custom/path.csv") # 直接生成标准52张牌 deck2 = Deck.generate_standard_deck()
内容的提问来源于stack exchange,提问作者LaidBackLuck
相关产品推荐
相关产品推荐

