protocols, inheritance and polymorphism

Dan Perl danperl at
Tue Nov 23 20:28:18 CET 2004

"Donn Cave" <donn at> wrote in message 
news:donn-F6A9D8.11153623112004 at
> In article <YWKod.137814$HA.44609 at attbi_s01>,
> Steven Bethard <steven.bethard at> wrote:
> ...
>> This is not to say that there are never any times when you want to use
>> isinstance.  Here's a good example from my code for a Bunch class[1]:
>> class Bunch(object):
>>      ...
>>      def update(self, *args, **kwds):
>>          if len(args) == 1:
>>              other, = args
>>              if isinstance(other, self.__class__):
>>                  other = other.__dict__
>>              try:
>>                  self.__dict__.update(other)
>>              except TypeError:
>>                  raise TypeError('cannot update Bunch with %s' %
>>                                  type(other).__name__)
>>          elif len(args) != 0:
>>              raise TypeError('expected 1 argument, got %i' % len(args))
>>          self.__dict__.update(kwds)
>> In the code here, we use isinstance to check on whether or not to use
>> the argument's __dict__.
> ...
>> The point here is that I'm using isinstance here because I *know* there
>> are objects out there that, unlike Bunch objects, may have 'attributes'
>> not stored in their __dict__, and I *know* they might get passed to
>> Bunch.update.  Since I can't appropriately support their use, I want the
>> user to be notified of this (with the TypeError).
>> Of course, I'm still making heavy use of the more general parametric
>> polymorphism because even if the object doesn't inherit from Bunch, I
>> still pass it to dict.update, which works with any type that supports
>> the mapping protocol (and a few other types besides).  So if, in the
>> future dict.update gains support for some new type, my code doesn't
>> artifically restrict the type of parameter that can be passed to my
>> function.
>> Hope this was helpful (or at least vaguely intelligible) ;)
> I don't really see that isinstance() was necessary in principle
> here.  Not that it makes any difference to me, but it looks like
> you created this problem by defining these semantics in Bunch
> but failing to assign any identifiable attribute - we could in
> principle make another unrelated class "quack like a Bunch",
> but we'd have no way to inform your update function of this.

I'm not sure what you mean by an "identifiable attribute", but I think we 
are going back to an issue I pointed out in another posting in this thread. 
It makes a huge difference whether your code is something that only you are 
using and changing during the next few weeks or it's an off-the-shelf 
library that will be maintained and changed for years from now and will be 
used by many clients.  What is "identifiable" to you (or even to someone in 
the next cubicle) for the next few weeks may not be identifiable a few years 
from now or to someone who downloaded your module from the web.

I hope this was "at least vaguely intelligible"!


>   Donn Cave, donn at 

More information about the Python-list mailing list