isinstance() considered harmful

kosh at kosh at
Thu Jan 24 18:37:53 EST 2002

On Thu, 24 Jan 2002, Kragen Sitaker wrote:

> Kosh writes:
> > However I do see it as useful to make base classes that esentially
> > do nothing but instead encapsulate some kind of behavior so that you
> > can use isinstance to test if an object implements that kind of
> > behavior.  Otherwise how would you test if an object was able to
> > work in a listish type way. You don't want to check every method
> > needs to indexing, len etc when you work with the object all the
> > time however if you put all those methods in a base class with just
> > pass for an implementation then you can test for an insinstance of
> > that class and find out very quickly if it is some kind of list
> > capable object.
> Well, if you use it as if it were a list, and it isn't, it will raise
> an exception.  Which I assume is what you do if the isinstance() test
> fails, right?  The only difference is that the exception will be an
> AttributeError: __len__ or something like that, instead of whatever
> hopefully more specific exception you raise if your isinstance()
> fails, which will hopefully make it easier for the person who wrote
> the calling code to fix things.

Well try except is slower then if else and rendering pages to the screen
does have a time limit to it so speed is a pretty importance factor. Also
while it is a listish object it is not a list. It supports a certain
feature set that behaves like a list but in other ways it does not. I just
need to be able to test for a behavior set which isinstance does allow you
to do if you but behaviors into a class that you mixin.

> Implementing all those methods in a base class with "pass" is a really
> stupid idea, unless it's semantically correct for that method to do
> nothing, because it turns broken code that would raise exceptions into
> broken code that silently gives wrong answers.  If someone implements,
> say, append() but not extend(), and their object gets passed to a
> routine that does both, then that routine will think it has added
> stuff with both append() and extend(), but actually only the stuff it
> added with append() will get there.  And you'll be debugging (or maybe
> trying to explain to a customer why they got the wrong answer) to try
> to figure out where those other values went.

You could replace pass with a raise of a NotImplementedError however in
practice that has not been a problem.
> If that's the case, then someone passing in an argument that isn't the
> right type won't happen either.

However what happens when you want to call all objects that are x kind of
object where x is a behavior.

Designing and building web applications

More information about the Python-list mailing list