在 __init__ 内调用 @classmethod
calling a @classmethod within __init__
所以我尝试采用 OOP 方法来制作一副纸牌,它将由一张纸牌 class 和一副纸牌 class 组成。
我有一个 .csv 文件,其中包含每张牌(52 张牌)的 2 列(花色和点数)。
suit,rank
Spades,2
Spades,3
Spades,4...
这里是 Card
Class 的简单版本,用于在 Deck
Class.
中创建卡片的每个实例
class Card:
def __init__(self, suit, rank):
self.suit = suit
self.rank = rank
self.name = f"{self.rank} of {self.suit}"
对于我的套牌 class 的 __init__
部分,我有几个循环可以打开 .csv 文件并将每个实例附加到空列表 self.cards
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)
我想知道它是否更优化,以及是否有办法将这些循环分配到 @classmethod
。我知道 @classmethod
调用 __init__
但是否可以反过来做?即
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)
如果您要从现有实例的 __init__
方法中调用 create_deck
方法,那么将其作为 class 方法是没有意义的。将它作为一个常规的、未修饰的实例会更有意义,以 self
作为它的参数:
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)
如果您需要替代构造函数,class方法很有用。它是你称之为 而不是 的东西 class 本身,它会为你创建实例:
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
现在您可以使用 Deck()
创建一个空牌组,或者使用 Deck.create_deck()
从 CSV 文件加载的卡片创建一个牌组。
所以我尝试采用 OOP 方法来制作一副纸牌,它将由一张纸牌 class 和一副纸牌 class 组成。
我有一个 .csv 文件,其中包含每张牌(52 张牌)的 2 列(花色和点数)。
suit,rank
Spades,2
Spades,3
Spades,4...
这里是 Card
Class 的简单版本,用于在 Deck
Class.
class Card:
def __init__(self, suit, rank):
self.suit = suit
self.rank = rank
self.name = f"{self.rank} of {self.suit}"
对于我的套牌 class 的 __init__
部分,我有几个循环可以打开 .csv 文件并将每个实例附加到空列表 self.cards
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)
我想知道它是否更优化,以及是否有办法将这些循环分配到 @classmethod
。我知道 @classmethod
调用 __init__
但是否可以反过来做?即
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)
如果您要从现有实例的 __init__
方法中调用 create_deck
方法,那么将其作为 class 方法是没有意义的。将它作为一个常规的、未修饰的实例会更有意义,以 self
作为它的参数:
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)
如果您需要替代构造函数,class方法很有用。它是你称之为 而不是 的东西 class 本身,它会为你创建实例:
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
现在您可以使用 Deck()
创建一个空牌组,或者使用 Deck.create_deck()
从 CSV 文件加载的卡片创建一个牌组。