Python Data Model
Pithy
Python Data Model is the API we use to make our own objects play well with the most idiomatic language features (stdlib)
The data model is a description of Python as a framework. It formalizes the interfaces of the build blocks of the language itself.
The python interpreter invokes special methods to perofrm basic object operations, special method names are always written with double underscores __getitem__.
Question
Why use special methods and follow the python data model?
Answer
Not only is it easier to read:
- our objects can support and interact with fundamental language constructs, you don’t have to recreate the wheel you can just use stdlib
- we can get better performance as special methods can leverage CPython
Python
# French deck example from Fluent Python
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]
# Using the class
deck = FrenchDeck()
>>> len(deck)
52
>>> Card('Q', 'hearts') in deck
True
>>> for card in deck:
>>> print(card)
Card(rank='2', suit='spades')
Card(rank='3', suit='spades')Special Methods
You should never call special methods yourself, they’re meant only for the interpreter.
python
# bad
my_obj.__len__()
# good
len(my_obj)
# which in turn calls __len__()__repr__ & __str__
Python
def __repr__(self):
return f'Vector({self.x!r}, {self.y!r})'
def __str__(self):
return f'<{self.x}, {self.y}>'
# Example use
v = Vector(3, 4)
repr(v) # 'Vector(3, 4)' unambiguous, can recreate it
str(v) # '<3, 4>' readable, human friendlyPurpose: get the string representation of the object for inspection
- repr goal is to be unambiguous - if possible, match the source code necessary to re-create the represented object.
- str goal is to be readable
Example output of both
Python
str(today)
'2012-03-14 09:21:58.130922'
repr(today)
'datetime.datetime(2012, 3, 14, 9, 21, 58, 130922)'