[Tutor] Does composition only work with particular instances of objects?

boB Stepp robertvstepp at gmail.com
Fri Aug 14 07:25:31 CEST 2015


On Thu, Aug 13, 2015 at 11:46 PM, Zachary Ware
<zachary.ware+pytut at gmail.com> wrote:
> On Thu, Aug 13, 2015 at 11:31 PM, boB Stepp <robertvstepp at gmail.com> wrote:
>> I was looking at an example illustrating composition from the book,
>> "Introducing Python" by Bill Lubanovic on p. 140:
>>
>>>>> class Bill:
>>         def __init__(self, description):
>>             self.description = description
>>
>>>>> class Tail:
>>         def __init__(self, length):
>>             self.length = length
>>
>>>>> class Duck:
>>         def __init__(self, bill, tail):
>>             self.bill = bill
>>             self.tail = tail
>>         def about(self):
>>             print('This duck has a', bill.description, 'bill and a',
>>                   tail.length, 'tail.')
>>
>> Here I was mildly surprised that bill and tail were not Bill and Tail,
>> and in the about method that self.bill was not used in place of
>> bill.description, etc.

Well, I was wrong about "Bill" and "Tail", but, then again, that came
from trying to make the flawed example work as I thought it should
work with things like:

class Duck:
    def __init__(self, Bill, Tail):
        self.bill = Bill.__init__.description
        etc.

Which, of course, I could not make work.  But I should have explored
adding the "self" where I thought it should have been used.

> Something went wrong here, either with the example itself or your
> copying of it...

Alas, it is an error in the book.  The only alteration I made in the
author's code was to drop the parentheses after the class names, that
is, I used "class Bill:" instead of the author's "class Bill():".  I
also added a "." after "'tail'" in the about method, but that truly is
an itty, bitty thing.


> ...Your instinct is correct, it should be
> 'self.bill.description' rather than 'bill.description': the Duck.about
> method as written above will only work in situations where 'bill' and
> 'tail' happen to be defined in the calling scope.  The about method
> should be:
>
>    def about(self):
>        print('This duck has a', self.bill.description,
>              'bill and a', self.tail.length, 'tail.')
>
>
>> Continuing:
>>
>>>>> tail = Tail('long')
>>>>> bill = Bill('wide orange')
>>>>> duck = Duck(bill, tail)
>>>>> duck.about()
>> This duck has a wide orange bill and a long tail.
>
> Before you fix the about method as I suggested above, try this again
> but do `del bill, tail` before you call `duck.about()`; the failure
> may be somewhat enlightening.

Yeah, I was dead certain that the book's example as written would only
work for the particular objects "bill" and "tail" and not for any
objects used for those in "Duck(bill, tail)" and this made absolutely
no sense to me.  Why limit composition to work with only particular
instances of objects???  I probably should have gone ahead and played
with the substitutions you suggested.  "bill.description" and
"tail.length" just did not make any sense to me.

Thanks, Zach!  I will have to see if the book has an errata site.

boB


More information about the Tutor mailing list