2012-11-30 94 views
2

如何將「in」關鍵字擴展到我創建的類?我正在製作一個Card類的紙牌遊戲。還有另外一類是玩家的手。基本上我想看看某張牌是否在手中。類比如下:python「in」類申請

>>> 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 

OK,所以我加了這段代碼在手類:

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 

它在終端說虛假...爲什麼?

回答

1

@BrenBarn給你一個指針在正確的方向看__contains__。但是,正如我對他的回答評論的那樣,實施該方法可能會要求您的對象具有可比性。現在,如果兩張卡片都是同一個物體,它們只會看起來相同。

對於我的意思的例子,試試這個:

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類具有「吸氣」方法的西裝和等級。這些在Python中通常是不必要的,在這裏你通常可以使用公共變量編程一切。也就是說,任何目前稱爲card.get_suit的應該只是訪問card.suit

在一些不常見的情況下,如果您需要爲響應變量訪問而執行復雜的操作(例如在請求時計算某些值或者阻止分配某些值),則可以在類中放入一個Property實例通常作爲函數的裝飾器),外部代碼仍然可以訪問它,就好像它仍然是一個公共變量。有許多getter的代碼在其他編程語言中很常見,它們不能在常規變量和像Python這樣的屬性之間切換。

+0

感謝您的幫助! – user1527227

4

您正在尋找神奇的方法__contains__

至於len,你的實現給出了正確的結果,但是不必要的複雜。你可以這樣做:

def __len__(self): 
    return len(self.hand) 
+0

感謝您的快速響應。你能告訴我如何實現__contains__和它會去的地方嗎? – user1527227

+1

@ user1527227:Googling「python'__contains__'例子」會給你很多例子。 – BrenBarn

+0

你可以把它交給你的內部列表,就像@ BrenBarn的回答爲'__len__'方法所做的那樣。 '高清__contains __(自我,卡): 高清__contains __(自我,卡):在self.hand' – Blckknght