16.01.2014 Views

Beginning Python - From Novice to Professional

Beginning Python - From Novice to Professional

Beginning Python - From Novice to Professional

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

CHAPTER 9 ■ MAGIC METHODS, PROPERTIES, AND ITERATORS 177<br />

As you can see from this example, once the bird has eaten, it is no longer hungry. Now<br />

consider the subclass SongBird, which adds singing <strong>to</strong> the reper<strong>to</strong>ire of behaviors:<br />

class SongBird(Bird):<br />

def __init__(self):<br />

self.sound = 'Squawk!'<br />

def sing(self):<br />

print self.sound<br />

The SongBird class is just as easy <strong>to</strong> use as Bird:<br />

>>> sb = SongBird()<br />

>>> sb.sing()<br />

Squawk!<br />

Because SongBird is a subclass of Bird, it inherits the eat method, but if you try <strong>to</strong> call it,<br />

you’ll discover a problem:<br />

>>> sb.eat()<br />

Traceback (most recent call last):<br />

File "", line 1, in ?<br />

File "birds.py", line 6, in eat<br />

if self.hungry:<br />

AttributeError: SongBird instance has no attribute 'hungry'<br />

The exception is quite clear about what’s wrong: the SongBird has no attribute called<br />

'hungry'. Why should it? In SongBird the construc<strong>to</strong>r is overridden, and the new construc<strong>to</strong>r<br />

doesn’t contain any initialization code dealing with the hungry attribute. To rectify the situation,<br />

the SongBird construc<strong>to</strong>r must call the construc<strong>to</strong>r of its superclass, Bird, <strong>to</strong> make sure that the<br />

basic initialization takes place. There are basically two ways of doing this: calling the unbound<br />

version of the superclass’s construc<strong>to</strong>r, and using the super function. In the next two sections<br />

I explain both.<br />

■Note Although this discussion centers around overriding construc<strong>to</strong>rs, the techniques apply <strong>to</strong> all methods.<br />

Calling the Unbound Superclass Construc<strong>to</strong>r<br />

If you find the title of this section a bit intimidating, relax. Calling the construc<strong>to</strong>r of a superclass<br />

is, in fact, very easy (and useful). I’ll start by giving you the solution <strong>to</strong> the problem posed<br />

at the end of the previous section:<br />

class SongBird(Bird):<br />

def __init__(self):<br />

Bird.__init__(self)<br />

self.sound = 'Squawk!'<br />

def sing(self):<br />

print self.sound

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!