So I'm trying to take an OOP approach to make a deck of cards that will be composed of a card class and a deck class.
I have a .csv file that consists of 2 columns (suits and ranks) for each card (52 cards).
suit,rank
Spades,2
Spades,3
Spades,4...
Here is a simple version of the Card
Class to create each instance of a card in the Deck
Class.
class Card:
def __init__(self, suit, rank):
self.suit = suit
self.rank = rank
self.name = f"{self.rank} of {self.suit}"
For the __init__
part of my deck class, I have a couple of loops to that opens the .csv file and appends each instance into the empty list self.cards
of the Deck
Class.
import csv
from cards import Card
cards_csv = "C/:path...."
class Deck:
def __init__(self):
self.cards = []
with open(cards_csv, "r") as f:
reader = csv.DictReader(f)
deck = list(reader)
for card in deck:
card = Card(
suit=str(card.get("suit")),
rank=str(card.get("rank"))
)
self.cards.append(card.name)
I was wondering would it be more optimal, and also if there was a way to assign those loops into a @classmethod
. I know the @classmethod
calls __init__
but is it possible to do it the other way around? i.e.
class Deck:
def __init__(self):
self.cards = []
self.create_deck()
@classmethod
def create_deck(cls):
with open(cards_csv, "r") as f:
reader = csv.DictReader(f)
deck = list(reader)
for card in deck:
card = Card(
suit=str(card.get("suit")),
rank=str(card.get("rank"))
)
cls.append(card.name)
CodePudding user response:
It doesn't make sense for create_deck
to be a classmethod if you're going to call it from the __init__
method of an already existing instance. It would make more sense for it to be a regular, undecorated instance, taking self
as its argument:
def create_deck(self):
with open(cards_csv, "r") as f:
reader = csv.DictReader(f)
deck = list(reader)
for card in deck:
card = Card(
suit=str(card.get("suit")),
rank=str(card.get("rank"))
)
self.cards.append(card.name)
A classmethod is useful if you want an alternative constructor. It is something you call instead of the class itself, and it handles creating the instance for you:
class Deck:
def __init__(self):
self.cards = []
# don't call create_deck here, it's now an optional alternative constructor
@classmethod
def create_deck(cls):
with open(cards_csv, "r") as f:
reader = csv.DictReader(f)
deck = list(reader)
inst = cls() # create the instance
for card in deck:
card = Card(
suit=str(card.get("suit")),
rank=str(card.get("rank"))
)
inst.cards.append(card.name) # append to the new instance's cards list
return inst
Now you can create an empty deck with Deck()
, or create one with cards loaded from the CSV file with Deck.create_deck()
.