Search code examples
python-3.xcontainsmagic-methods

Python Data Model : Overriding special method "contains"


So I am trying to understand python better with the book "Fluent Python". In python data model the author describes how special methods can be defined for classes.

class FrenchDeck:
      ranks = [str(n) for n in range(2,11)] + list('JQKA')
      suits = 'spades diamonds clubs hearts'.split()

      def __init__(self):
          self._cards = [Card(rank,suit) for rank in self.ranks
                                    for suit in self.suits]

      def __len__(self):
          return len(self._cards)

      def __getitem__(self,position):
          return self._cards[position]

      def __contains__(self,*args):
          return "Contains has been overridden"
deck  = FrenchDeck()
print(Card('Q','hearts') in deck)

Running the above code gives me the following result, whereas I expect it to say "Contains has been overridden"

True

Why can't I override contains?


Solution

  • I think your situation is the combination of many things:

    So since you returned a non-empty string, it was evaluated as a True value. If you changed it to an empty string your will have a value of False. Here's an example:

    import dataclasses
    
    @dataclasses.dataclass
    class Card:
        rank: str
        suit: str 
    
    class FrenchDeck:
        ranks = [str(n) for n in range(2,11)] + list('JQKA')
        suits = 'spades diamonds clubs hearts'.split()
    
        def __init__(self):
            self._cards = [Card(rank, suit) for rank in self.ranks
                                    for suit in self.suits]
    
        def __len__(self):
            return len(self._cards)
    
        def __getitem__(self, position):
            return self._cards[position]
    
        def __contains__(self, item):
            return ""
    
    deck  = FrenchDeck()
    print(Card('Q','hearts') in deck)
    

    But don't try to change fundamentally the meaning of a magic method like you did here. It will confuse other people (including your future self)