2

如何将“in”关键字扩展到我创建的类?我正在使用 Card 类制作纸牌游戏。还有另一个类是玩家的手。基本上我想看看某张牌是否在手中。一个类比如下:

>>> 5 in range(0, 5)
True

这是我的代码。我有一个 Hand 类,我想看看 Card() 是否在 Hand()

另外,我对这个类的概念很陌生。我才刚刚开始了解这整件事是如何运作的。我是否正确实现了len方法?

class Card:
    def __init__(self, suit, rank):
        # self.suit > str
        # self.rank > str
        if (suit in SUITS) and (rank in RANKS):
            self.suit = suit
            self.rank = rank
        else:
            self.suit = None
            self.rank = None
            print "Invalid card:", suit, rank

    def __str__(self):
        return self.suit + self.rank

    def get_suit(self):
        return self.suit

    def get_rank(self):
        return self.rank


# define hand class
class Hand:
    # A list of Card objects
    # adding cards to the hand should remove cards from the deck.

    def __init__(self):
        self.hand = []

    def __str__(self):
        cards = []
        for card in self.hand:
            cards += [card.get_suit() + card.get_rank()]
        return str(cards)

    def add_card(self, card):
        return self.hand.append(card)

    def __len__(self):
        counter = 0
        for card in self.hand:
            counter +=1
        return counter

好的,所以我在手类中添加了这段代码:

    def __contains__(self, card):
        return card in self.hand

但我尝试测试我的代码但它不起作用:

c = Card('H','A')

h = Hand()
h.add_card(Card('S','K'))
h.add_card(Card('D','A'))
h.add_card(Card('H','A'))

print 'hand=', h
print 'c=', c
print 'c in h', c in h

它在终端中显示 False ......为什么?

4

2 回答 2

4

你正在寻找__contains__神奇的方法。

至于len,您的实现给出了正确的结果,但不必要地复杂。你可以这样做:

def __len__(self):
    return len(self.hand)
于 2012-11-30T07:26:28.570 回答
1

@BrenBarn 给了你一个指向正确方向的指针__contains__。但是,正如我对他的回答所评论的那样,实现该方法可能需要您的Card对象具有可比性。现在,只有当它们都是同一个对象时,两张牌才会显得相等。

对于我的意思的一个例子,试试这个:

c1 = Card("H", "A")
c2 = Card("H", "A")

print c1 == c2 # False!

要解决此问题,您需要将__eq__方法添加到您的Card类(可能还添加__ne__方法,这样您就可以使用!=测试)。这是一个可能的实现:

def __eq__(self, other):
    return self.suit == other.suit and self.rank == other rank

def __ne__(self, other):
    return not self == other

我想指出另一件事(与您的问题无关)。你的Card班级有西装和等级的“getter”方法。在 Python 中这些通常是不必要的,在 Python 中,您通常可以首先使用公共变量对所有内容进行编程。也就是说,当前调用的任何内容card.get_suit都应card.suit改为访问。

在不太常见的情况下,您需要做复杂的事情来响应变量访问(例如在请求时计算某些值,或阻止分配某些值),您可以Property在类中放置一个实例(通常作为装饰器一个函数),并且外部代码仍然可以访问它,就好像它仍然是一个公共变量一样。具有大量 getter 的代码在其他编程语言中很常见,这些编程语言无法在常规变量和 Python 等属性之间切换。

于 2012-11-30T08:17:14.507 回答