Is there a consensus on how to check a polymorphic instance?

Steven Bethard steven.bethard at gmail.com
Tue Nov 23 05:32:57 CET 2004


Mike Meng wrote:
> I'm a newbie Python programmer with a C++ brain inside. I have a
> lightweight framework in which I design a base class and expect user to
> extend. In other part of the framework, I heavily use the instance of
> this base class (or its children class). How can I ensure the instance
> IS-A base  class instance, since Python is a fully dynamic typing
> language?

The short answer is that if you want to ensure an instance is-a subclass 
of the base class, you should use isinstance:

 >>> class HasF(object):
...     def f(self):
...         raise NotImplementedError
...
 >>> class SubHasF(HasF):
...     def f(self):
...         return self.__class__
...
 >>> class NonsubHasF(object):
...     def f(self):
...         return self.__class__
...
 >>> isinstance(SubHasF(), HasF)
True
 >>> isinstance(NonsubHasF(), HasF)
False

However it's often not necessary to go this route.  Consider:

 >>> class HasNoF(object):
... 	pass
...
 >>> def use_c(c):
...     try:
...         f = c.f
...     except AttributeError:
...         raise TypeError('argument to use_c must have an f method')
...     return f()
...
 >>> use_c(SubHasF())
<class '__main__.SubHasF'>
 >>> use_c(NonsubHasF())
<class '__main__.NonsubHasF'>
 >>> use_c(HasNoF())
Traceback (most recent call last):
   File "<interactive input>", line 1, in ?
   File "<interactive input>", line 5, in use_c
TypeError: argument to use_c must have an f method

Is it really necessary that the classes passed to your equivalent of 
'use_c' are actually subclasses of your equivalent to 'HasF'?  Or is it 
just necessary that they support the appropriate methods?  If it's the 
second, I would just test for the appropriate methods and catch the 
AttributeErrors (and possibly the TypeError that's thrown if 'f' isn't 
callable).

If you can give a little more detail on your particular example, I (and 
others) can probably give you more helpful suggestions...

Steve



More information about the Python-list mailing list