Extending Built-In Classes
We can extend all of Python's built-in classes. This allows us to
add or modify features of the data types that come with Python. This may
save us from having to build a program from scratch. We'll look at an
extended example of creating a specialized dictionary.
A common database technique is to create an index to a set of
objects. The index contains key fields; each key is associated with a
list of objects that share that key.
Let's say we have a StockBlock
class, which
includes the ticker symbol. We may have many small blocks of the same
stock in a simple sequence. Our index mapping has a key of the ticker
symbol; the value is a sequence of StockBlock
objects that share the ticker symbol.
class StockBlock( object ):
def __init__( self, ticker, price, shares ):
...
We'd like to do something like the following.
index = Index()
for block in portfolio:
index[block.ticker].append( block )
As written, this won't work. What happens when we evaluate
index['CTG'] before 'CTG' is a key in the dictionary?
Here's our Index class definition; it extends the built-in
dict
class. We use the super
function to refer to the original dict implementation to which we adding
features. In this case, we only want to extend the
__getitem__
method to provide a handy default
value.
class Index( dict ):
def __getitem__( self, key ):
if not self.has_key( key ):
super(Index,self).__setitem__( key, [] )
return super(Index,self).__getitem__( key )
Since our subclass is based on dict
, it
does everyting the built-in class does.
This is similar to the defaultdict
class in
the collections
module. This can also be
accomplished by defining the __missing__
special method of a dictionary subclass.