我现在正在自学Python,来到了关于继承的类(class),所以这是我第一次接触子类。我正在从“Think Python”一书中学习,该示例是关于创建代表扑克牌、牌组、手牌等的类。以下示例是从本书中复制的(我自己添加了一个或两个方法,作为练习):
import random
from operator import itemgetter, attrgetter
class Card:
"""represents a standard playing card."""
def __init__(self, suit=0, rank=2):
self.suit = suit
self.rank = rank
suit_names = ['Clubs', 'Diamonds', 'Hearts', 'Spades']
rank_names = [None, 'Ace', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'Jack', 'Queen', 'King']
def __str__(self):
return '%s of %s' % (Card.rank_names[self.rank], Card.suit_names[self.suit])
def __cmp__(self, other):
t1 = self.suit, self.rank
t2 = other.suit, other.rank
return cmp(t1, t2)
class Deck:
"""represents a standard deck of cards"""
def __init__(self):
self.cards = []
for suit in range(4):
for rank in range(1, 14):
card = Card(suit, rank)
self.cards.append(card)
def __str__(self):
res = []
for card in self.cards:
res.append(str(card))
return '\n'.join(res)
def pop_card(self):
return self.cards.pop()
def add_card(self):
self.cards.append(card)
def shuffle(self):
random.shuffle(self.cards)
def sort(self):
self.cards.sort(key=attrgetter('suit', 'rank'))
class Hand(Deck):
"""represents a hand of playing cards"""
def __init__(self, label=''):
self.cards = []
self.label = label
def move_cards(self, hand, num):
for i in range(num):
hand.add_card(self.pop_card())
我的问题是 Hand 子类方法。如果我尝试从 Hand 子类调用 move_cards 方法,例如使用 a = Deck()
、b = Hand()
,尝试调用 move_cards (b,2)
或 a.move_cards(b,2)
给我相同的 AttributeError: 'Deck' 对象没有属性 'move_cards'
。
为什么会发生这种情况或者我做错了什么?谢谢。
最佳答案
move_cards
仅为子类 Hand
定义,而不是为父类 Deck
定义。
我认为示例中的继承顺序令人困惑 - Hand
并不真正感觉像是 Deck
的子类,相反,它们都应该是公共(public)的子类卡片收集(Stack
说)。例如(未测试):
class Stack:
"""represents a collection of cards"""
def __init__(self):
self.cards = []
def __str__(self):
res = []
for card in self.cards:
res.append(str(card))
return '\n'.join(res)
def pop_card(self):
return self.cards.pop()
def add_card(self):
self.cards.append(card)
def shuffle(self):
random.shuffle(self.cards)
def sort(self):
self.cards.sort(key=attrgetter('suit', 'rank'))
def move_cards(self, dest, num):
for i in range(num):
dest.add_card(self.pop_card())
class Deck(Stack):
"""represents a deck of playing cards"""
def __init__(self):
Stack.__init__(self)
for suit in range(4):
for rank in range(1, 14):
card = Card(suit, rank)
self.cards.append(card)
class Hand(Stack):
"""represents a hand of playing cards"""
def __init__(self, label=''):
Stack.__init__(self)
self.label = label
请注意子类 Hand
和 Deck
的重写构造函数如何使用 Stack.__init__(self)
显式调用父构造函数。这会以相同的方式初始化每个成员的 self.cards 成员。
关于Python子类调用父类的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20422697/