简体   繁体   English

父类的Python子类调用方法

[英]Python subclass invoking method from parent class

I'm currently self-learning Python, and I came to the lesson about inheritance, so this is my first experience with subclasses. 我目前正在自学Python,并且上了有关继承的课程,因此这是我对子类的第一次体验。 I'm learning from the book "Think Python", and the example is about creating classes that represent playing cards, decks, hands etc. The following example is copied from this book (with myself added method or two, as an exercise): 我正在从“ 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())

My problem is with the Hand child class methods. 我的问题是Hand子类方法。 If I try to invoke the move_cards method from the Hand child class, for example with a = Deck() , b = Hand() , trying to invoke move_cards(b,2) , or a.move_cards(b,2) gives me the same AttributeError: 'Deck' object has no attribute 'move_cards' . 如果我尝试从Hand子类中调用move_cards方法,例如使用a = Deck()b = Hand() ,尝试调用move_cards(b,2)a.move_cards(b,2)会给我相同的AttributeError: 'Deck' object has no attribute 'move_cards'

Why is this happening or what I am doing wrong? 为什么会发生这种情况,或者我做错了什么? Thanks. 谢谢。

move_cards is only defined for the subclass Hand , not the parent class Deck . move_cards仅为子类Hand定义,而不为父类Deck

I think the order of inheritance is confusing in the example - Hand doesn't really feel like a subclass of Deck , rather they should both be subclasses of a common card collection ( Stack say). 我认为示例中的继承顺序令人困惑Hand并没有真正感觉像Deck的子类,而是它们都应该是普通卡片收藏的子类( Stack说)。 For example (not tested): 例如(未测试):

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

Notice how the overrided constructors for the subclasses Hand and Deck call the parent constructor explicitly with Stack.__init__(self) . 注意子类HandDeck的重写构造函数如何使用Stack.__init__(self)显式调用父构造函数。 This initialises the self.cards member in the same way for each. 这以相同的方式初始化self.cards成员。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM