[Tutor] design questions: pythonic approach to ostriches

Kent Johnson kent37 at tds.net
Sat Apr 23 19:58:59 CEST 2005


Brian,

I think you have done a great job of demonstrating that design has to be evaluated in the light of 
requirements. There are probably scenarios where each of these solutions makes sense. Without 
knowing how it is to be used, there is no way to pick the 'right' one.

For example in a bird simulation it might be fine to have Ostrich.fly() do nothing. Possibly the 
version that throws an exception would be useful there also. The class hierarchy with FlyingBird is 
maybe more 'correct' but I don't know that it would be any easier to use in practice.

If you make Ostrich.fly() raise AttributeError it will look to the caller like it is not 
implemented...NotImplementedError seems appropriate as well. If you want to define your own 
exception it can be as simple as
class FlightlessBirdException(Exception):
   pass

Kent

Brian van den Broek wrote:
> Hi all,
> 
> I am wondering about the Pythonic way to handle the problem of 
> ostriches, emus, and penguins. (I cannot recall from where I got the 
> example.)
> 
> Here's what I mean:
> 
> class Bird(object):
>     def fly(self):
>         # flying logic here
>     def lay(self):
>         # egg-laying logic here
>     # more bird methods
> 
> class Ostrich(Bird):
>     # ostriches can't fly, so what to do?
> 
> I've explored a number of solutions; here they are with what I see as to 
> cons and problems:
> 
> 
> The simplest thing is to emulate the ostrich and pretend the problem 
> doesn't exist. But, putting one's head in the sand looks likely to cause 
> troubles in that this route break encapsulation, requiring callers to 
> know enough not to call the fly method of an ostrich. So, that's no good.
> 
> 
> class Ostrich(Bird):
>     def fly(self):
>         pass
> 
> seems only marginally better, in that it gives the external appearance 
> of flight, whereas what is needed is a "Hey, I don't fly" signal.
> 
> 
> The next thought was to over-ride Ostrich.fly as
>     def fly(self):
>          raise NotImplementedError
> 
> That seems better, but also a bit confusing; the way I understand it, 
> NotImplementedError is, in the first instance, for abstract classes or 
> for marking work in progress. But Ostrich.fly doesn't fit either case.
> 
> 
> That makes me think to define a custom exception, say
> 
> class OstrichError(NotImplementedError):
>     '''A custom exception for cases of the "Ostrich problem".
> 
>     Intended to be raised by methods in a subclass over-riding methods
>     of the parent which don't make sense for the subclass to actually
>     implement.'''
>     def __init__(self):
>         NotImplementedError.__init__(self)
> 
> But, since the problem isn't one that my penetrating genius discovered, 
> I am inclined to think that were this the ideal solution, there'd be a 
> (better named) exception class builtin to Python already.
> 
> 
> A complicated class hierarchy like
> 
> class Bird(object):
>     # bird logic
> 
> class FlyingBird(Bird):
>     def fly(self):
>         # flying logic here
> 
> class FlightlessBird(Bird):
>     # any particularly flightless logic here
> 
> class Ostrich(FlightlessBird):
>     # ostrich logic
> 
> seems an invitation to difficulty. My analogy will soon break, but some 
> birds build nests and sing, others, no so much, etc. Flat is soon to 
> give way to deeply nested.
> 
> 
> I also tried to delete the inherited Bird.fly method within 
> Ostrich.__init__, but
> 
> class Ostrich(Bird):
>     def __init__(self):
>         del self.__dict__['fly']
> 
> raises a KeyError, whereas
> 
>     def __init__(self):
>         del Ostrich.__dict__['fly']
> 
> raises:
> TypeError: object does not support item deletion
> 
> 
> Do I have the syntax of the last approach wrong? Or is there no way to 
> remove a method from a class? If the latter, what to do about flightless 
> fowl?
> 
> Thanks and best,
> 
> Brian vdB
> 
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> http://mail.python.org/mailman/listinfo/tutor
> 



More information about the Tutor mailing list