Type casting a base class to a derived one?

Chris Mellon arkanes at gmail.com
Wed Jan 24 19:57:11 CET 2007


On 1/24/07, Cliff Wells <cliff at develix.com> wrote:
> On Thu, 2007-01-11 at 08:41 -0600, Chris Mellon wrote:
> > On 11 Jan 2007 15:01:48 +0100, Neil Cerutti <horpner at yahoo.com> wrote:
> > > On 2007-01-11, Frederic Rentsch <anthra.norell at vtxmail.ch> wrote:
> > > > If I derive a class from another one because I need a few extra
> > > > features, is there a way to promote the base class to the
> > > > derived one without having to make copies of all attributes?
> > > >
> > > > class Derived (Base):
> > > >    def __init__ (self, base_object):
> > > >       # ( copy all attributes )
> > > >       ...
> > > >
> > > > This looks expensive. Moreover __init__ () may not be available
> > > > if it needs to to something else.
> > > >
> > > > Thanks for suggestions
> > >
> > > How does it make sense to cast a base to a derived in your
> > > application?
> > >
> >
> > I can't figure out any circumstance when you'd need to do this in
> > Python. Upcasting like this is something you do in statically typed
> > languages. I suspect that the OP doesn't really believe dynamic
> > casting works and doesn't want to pass a derived class for some
> > reason.
>
> I actually encountered a need to do so (and I recalled seeing this
> thread which is why I'm replying to it now).  I've got a dispatch system
> based on object type.  Objects come from an external source (an ORM), so
> I can't efficiently set their types at the point of creation (nor would
> I necessarily want to).  However, in different contexts, I may want them
> to be dispatched differently (i.e as if they are a different type).  In
> fact, often the same object will be handled differently within two or
> more contexts during the lifetime of that object.  It would be nice to
> be able to cast them to a derived class (which actually adds no new
> methods or attributes, just changes the type) at that exact moment to
> cause the dispatcher to handle them differently.
>

In Python, you can do this simply by re-assigning the __class__. I'm
not convinced that your type system makes sense, here though. Any
reasonable ORM should be able to persist and reload an object without
losing the type information. Perhaps it's just a blind spot in the way
I think about types. Assuming that the limitations of your ORM are
external and out of your control, I would still ensure that whatever
generic objects are being loaded from the ORM are converted into
"real" objects of the correct type as soon as possible. For example,
if you're persisting a file, you might just save the filename, and
your ORM might return a string of the filename. I would want to
convert that back into a file object ASAP, rather than writing all my
code to accept either a FLO or a string and converting then.

If you know what to upcast something to, then you know what type it
is. If you know what type it is, then (in Python) you can simply
assume it is of that type.

What you're describing is a disjoint between your actual type system
(that is, the one you have in code) and your theoretical type system
(the one that you model your code around). To me, this is a huge red
warning flag.

> Now, that being said, it's quite possible the system *could* have been
> designed to not dispatch based on type, but quite frankly it works quite
> elegantly and naturally for everything but this one case.
>

Dispatch on type is perfectly natural. I'm not arguing against that,
I'm arguing against the idea that it makes sense, in Python, to
upcast.

> Just pointing out that just because we don't see a need for something
> doesn't invalidate it.  It just makes it something we had thought of ;-)
>

I agree, but without a use case it's hard to understand the limits and
needs of a requirement. So if you can't think of a need for a feature,
it becomes difficult to understand how you might implement that
feature.



More information about the Python-list mailing list