In a way, a Python’s data model can be viewed as a framework. It formalizes the interfaces of the building blocks of the language itself.

The Python interpreter invokes special methods to perform basic object operations, often triggered by special syntax. That provides a consistency in usage of objects from standard library, as well as custom ones.

Example

  • __len__ special method will be called by the len() function
  • __getitem__ - used to read items from the sequence.
import collections
 
Card = collections.namedtuple('Card', ['rank', 'suit'])
 
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 suit in self.suits
                                        for rank in self.ranks]
 
    def __len__(self):
        return len(self._cards)
 
    def __getitem__(self, position):
        return self._cards[position]
>>> deck = FrenchDeck()
>>> len(deck)
52
>>> deck[0]
Card(rank='2', suit='spades')
>>> deck[-1]
Card(rank='A', suit='hearts')

Benefits

  • Users don’t have to memorize arbitrary methods names for standard operations (“How to get the number of items? Is it .size(), .length(), or what?”)
  • It’s easier to benefit from the rich Python standard library and avoid reinventing the wheel, like the random.choice function or the fact that with __getitem__ method we can read specific item in the sequence, slice or iterate it.