Boost logo

Boost :

From: Anton Gluck (gluc_at_[hidden])
Date: 2000-11-28 00:44:44


Dave,

> > > > I suggest writing isinstance() in Python something like this.
> > > >
> > > > # untested! (not needed For Python 2.0)
> > > > def _is_subclass(t1, t2):
> > > > for b in getattr(t1. '__bases__', ()):
> > > > if b is t2 or _is_subclass(b, t2):
> > > > return 1
> > > > return 0
> > > >
> > > > # untested! For Python 1.5 or 2.0
> > > > def is_instance(obj, type):
> > > > return isinstance(obj, type) or _is_subclass(getattr(obj,
> > '__class__',
> > > > None), type)
> > >
> > > I tried my luck with a very simple version of a custom isinstance(). I
> > > wrote it like this:
> > >
> > > def _is_instance(object, extensionclass):
> > > if object.__class__ == extensionclass:
> > > return 1
> > > else:
> > > return 0
> >
> > You are indeed rolling the dice here, Toni. Your technique won't work
> > because it never checks the __bases__ of an object's class. You need to walk
> > the inheritance hierarchy until you find the desired class, which is what my
> > version is supposed to do.
>
> In my case I am looking for an exact match between the object's class and
> whatever class I am checking against. I happen to know ahead of time that
> there are no further subclasses since this is the inheritance:
>
> ClusterVar
> / \
> CatVar ContVar

I have reconsidered this: My version is too limited to be a work-around
for isinstance(); a real work-around should be written the way you did. On
the other hand, my version works for the limited job I am using it for.
So, to make the limited use clear, I renamed it to is_CatVar_or_ContVar().
When I get around to it, I will test your version for general use.

> You are right, they are ClusterVar*s. But since I am using the iterator we
> discussed earlier to get to the vector elements, I am being given
> ClusterVars. Therefore, for all practical purposes, it might as well be a
> vector of ClusterVars. (The return type of getItem(), which retrieves
> vector elements, is ClusterVar. I have tried casting the ClusterVar to
> either CatVar or ContVar, but got errors like 'cannot cast from ClusterVar
> to CatVar'. I think this is where I need to look for a fix. Now that I
> think of it: perhaps I can rewrite getItem() to return ClusterVar*s. That
> might help.)

I've looked through the code and tried a few things, and came up with this
solution: I changed the return type from ClusterVar to ClusterVar* so that
Python will not receive a ClusterVar object without info on whether this
was a CatVar or ContVar. Since now I am returning a pointer I wrote a
to_python for this that examines the ClusterVar, casts it as CatVar or
ContVar accordingly, and then returns the object. Now Python will receive
actual CatVar and ContVar objects. In case somebody is interested, here is
the code for to_python:

PyObject* to_python(ClusterVar* cv)
{
    if (typeid(*cv) == typeid(CatVar)) {
        return to_python(dynamic_cast<CatVar&>(*cv));
    }
    else if (typeid(*cv) == typeid(ContVar)) {
        return to_python(dynamic_cast<ContVar&>(*cv));
    }
    else return to_python(*cv);
        // in case we have a genuine ClusterVar object
}

Many thanks for your input on this, Dave.

Toni


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk