Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions

  




 

 

Initializer Techniques

When we define a subclass, we are often extending some superclass to add features. One common design pattern is to do this by defining a subclass to use parameters in addition to those expected by the superclass. We must reuse the superclass constructor properly in our subclass.

Referring back to our Card and FaceCard example in the section called “Inheritance”, we wrote an initializer in FaceCard that referred to Card. The __init__ function evaluates super(FaceCard,self).__init__, passing the same arguments to the Card's __init__ function.

As an aside, in older programs, you'll often see an alternative to the super function. Some classes will have an explicit call to Card.__init__( self, r, s ). Normally, we evaluate object.method(), and the object is implicitly the self parameter. We can, it turns out, also evaluate Class.method( object ). This provides the object as the self parameter.

We can make use of the techniques covered in the section called “Advanced Parameter Handling For Functions” to simplify our subclass initializer.

class FaceCard( Card ):
    """Model a 10-point face card: J, Q, K."""
    def __init__( self, *args ):
        super(FaceCard,self).__init__( *args )
        self.label= ("J","Q","K")[self.rank-11]
        self.pval= 10
    def __str__( self ):
        return "%2s%s" % ( self.label, self.suit )

In this case we use the def __init__( self, *args ) to capture all of the positional parameters in a single list, args. We then give that entire list of positional parameters to Card.__init__. By using the * operator, we tell Python to explode the list into individual positional parameters.

Let's look at a slightly more sophisticated example.

Example 22.4. boat.py

class Boat( object ):
    def __init__( self, name, loa ):
        """Create a new Boat( name, loa )"""
        self.name= name
        self.loa= loa
class Catboat( Boat )
    def __init__( self, sailarea, *args ):
        """Create a new Catboat( sailarea, name, loa )"""
        super(Catboat,self).__init__( *args )
        self.mainarea= sailarea
class Sloop( CatBoat ):
    def __init__( self, jibarea, *args );
        """Create a new Sloop( jibarea, mainarea, name, loa )"""
        super(Sloop,self).__init__( *args )
        self.jibarea= jibarea
1

The Boat class defines essential attributes for all kinds of boats: the name and the length overall (LOA).

2

In the case of a Catboat, we add a single sail area to be base definition of Boat. We use the superclass initialization to prepare the basic name and length overall attributes. Then our subclass adds the sailarea for the single sail on a catboat.

3

In the case of a Sloop, we add another sail to the definition of a Catboat. We add the new parameter first in the list, and the remaining parameters are simply given to the superclass for its initialization.


 
 
  Published under the terms of the Open Publication License Design by Interspire