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

Carlos Ribeiro carribeiro at gmail.com
Tue Nov 23 15:22:04 EST 2004


On 22 Nov 2004 22:40:10 -0800, Mike Meng <meng.yan at gmail.com> wrote:
> hi Steve,
> Your example is helpful. Thank you.
> 
> Here is my problem. My project needs to parse some user input
> string according to  specific rules. The rules can be defined with a
> string, a CSV file, an XML file, and other forms. Followed the standard
> OO style,  I designed a dictionary-like base class to abstract those
> different sources and provides other parts a uniform interface to query
> those rules.  I put some hard code into the base class and expect user
> to inherit from it.

Your base class defines a "protocol" (loosely defined as a set of
methods, associated behavior & usage pattern). It's more than an
"interface", in strict C++/Java speak, because a protocol defines the
interaction between objects in a dynamic fashion.

In Python, you can use isinstance() to implement a safe, but somewhat
rigid, solution to your problem. Using hasattr() is another option,
that doesn't restrict you from using only derived classes; however,
it's more confusing, because you may mistake a partial implementation
of the protocol for a full one, depending on what & when you check.

The new-style approach to the problem is adaptation. I've written a
short article on adaptation, with some references to the adaptation
PEP, and also to PyProtocols, that is a recent implementation of the
idea that goes much further than the original PEP did. Some big
projects like Zope already use adaptation.

http://pythonnotes.blogspot.com/2004/11/what-is-adaptation.html

The use case for adaptation is as follows; you call adapt(object,
protocol), and the adapt call will return an object that is guaranteed
to support your protocol. Of course, if your object is from the
correct base class, then it's automatically returned. If the user
implements a new class from the scratch, but that happens to implement
your protocol, then he may implement the proper adaptation hooks to
make the adapt() call succeed.

The main advantage of using adaptation, in your case, is that it
cleans up the code somewhat. You call adapt() only once, and you can
simply use the object that is returned from it without fear. In
opposition to isinstance (which only does a simple inheritance check),
adapt() can do some work on the object it receives to 'transform' it
into a new object that supports the protocol. It's a much more dynamic
approach to the problem.

-- 
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: carribeiro at gmail.com
mail: carribeiro at yahoo.com



More information about the Python-list mailing list