next up previous contents
Next: Adding Methods to the Up: Writing Modules Previous: A First Example of   Contents

Inheritance

One of the biggest benefits of the class-based approach to programming is that classes can inherit attributes and methods from other classes. If you need to work with an object that's very similar to some other object that has already been developed, your new object can inherit all of the old object's methods, add new ones, and/or overwrite the ones which need to change.

Continuing with our little database example, suppose that you found the friend database so useful at home, that you'd like to extend it into a database to keep track of business contacts. It would be very helpful to have a few additional fields in the database, let's say a company name and the type of product that the company produces. Following the example of the Friend object, we could create a Contact object as follows:

class Contact:
    def __init__(self,name,company,phone='',email='',product=''):
        self.name = name
        self.company = company
        self.phone = phone
        self.email = email
        self.product = product

    def __str__(self):
        return 'Name: %s\nCompany: %s\nPhone: %s\nEmail: %s\nProduct: %s' % \
               (self.name,self.company,self.phone,self.email,self.product)
               
             
    def __repr__(self):
        return self.__str__()
Now we'd like to create an object that would let us store, add and search a database of contacts. The details of opening files, pickling, searching, and indexing really haven't changed - our Contactdb object can simply inherit all of them from the Frienddb object. The only real change is that now we'll be storing Contact objects in the list called db inside of the object instead of Friend objects, so we'll need to overwrite the add method:
from frienddb import Frienddb

class Contactdb(Frienddb):
    def add(self,name,company,phone='',email='',product=''):
        self.db.append(Contact(name,company,phone,email,product))
By putting the name of another class (Frienddb) in parentheses after the name of our new class (Contactdb) we're informing Python that this class will inherit methods and attributes from that old class. If we invoke a method or try to access an attribute that's been explicitly defined for our new class, Python will use the one we've defined. But if we refer to a method or attribute we haven't explicitly defined, it will refer to that method or attribute in the so-called ``parent'' class. (Python even supports multiple inheritance; if you have a comma-separated list of classes in parentheses after your class name, python will search each of them in turn for methods or attributes not explicitly defined for the new class.) Thus after simply defining the add method, we can create and use our contact database:
>>> import contactdb
>>> fdb.search('harry')
[Name: Harry Smith
Phone: 443-2199
Email: hsmith@notmail.com]
>>> cdb = contactdb.Contactdb('new.db')
>>> cdb.add('Mary Wilson','Brainpower, Inc.','222-3292',
...     'mw@brainpower.net','consulting')
>>> cdb.add('John Jenkins','Advanced Microstuff','321-9942',
...     'jjenkins@advmicro.com','disk drives')
>>> cdb.add('Fred Smith','Hitech Storage','332-1994',
...     'fredsmith@hitechstorage.com','magnetic tape')
>>> cdb.add('Al Watson',"Brains 'r Us",'335-2324',
...     'al@brains.net','consulting')
>>> cdb.search('mary')
[Name: Mary Wilson
Company: Brainpower, Inc.
Phone: 222-3292
Email: mw@brainpower.net
Product: consulting]
>>> cdb[3]
Name: Al Watson
Company: Brains 'r Us
Phone: 335-2324
Email: al@brains.net
Product: consulting
>>> cdb['John Jenkins']
Name: John Jenkins
Company: Advanced Microstuff
Phone: 321-9942
Email: jjenkins@advmicro.com
Product: disk drives
All of the methods we implemented for the Frienddb class work correctly with our new class. Since we defined a Contact object, and explicitly defined an add method to use it, Python knows how to display the contacts properly.

Now suppose that we want to expand the search method to allow us to specify, using a keyword argument, whether we wish to search the database for a name, a company or a product. We've already developed a method to search for names when we wrote the Frienddb class, so we can use that when we're searching for names, and add additional code to handle the other cases. When you need to access a method from another class, you need to treat the method like a regular function. In other words, instead of following self with the method name, you call the function with self as the first argument to the method, as illustrated below when the search method from the Frienddb class is invoked in our new search method:

    def search(self,name='',company='',product=''):
        results = []
        if name:
            found = Frienddb.search(self,name)
            results.extend(found)

        if company:
            srch = re.compile(company,re.I)
            found = []
            for item in self.db:
                if srch.search(item.company):
                    found.append(item)
            results.extend(found)
            
        if product:
            srch = re.compile(product,re.I)
            found = []
            for item in self.db:
                if srch.search(item.product):
                    found.append(item)
            results.extend(found)

        return results
(As in previous examples, this method would only make sense if it was part of the definition for the class Contactdb.) Now we can search for either names, companies or products:
>>> cdb = contactdb.Contactdb('new.db')      
>>> found = cdb.search(product='consult')
>>> for i in found:
...     print '-' * 10
...     print i
...
----------
Name: Mary Wilson
Company: Brainpower, Inc.
Phone: 222-3292
Email: mw@brainpower.net
Product: consulting
----------
Name: Al Watson
Company: Brains 'r Us
Phone: 335-2324
Email: al@brains.net
Product: consulting
>>> found = cdb.search(name='mary')
>>> print found[0]
Name: Mary Wilson
Company: Brainpower, Inc.
Phone: 222-3292
Email: mw@brainpower.net
Product: consulting


next up previous contents
Next: Adding Methods to the Up: Writing Modules Previous: A First Example of   Contents
Phil Spector 2003-11-12