python constructor overloading

Gordon McMillan gmcm at hypernet.com
Fri Dec 17 16:08:14 EST 1999


Greg Copeland wrote:

> Gordon McMillan wrote:
> > 
[circular references 'twixt objects and container]
 
> > Bzzt. The container is unavailable, but unless you specifically
> > clear it, it will still exist, because it's ref count hasn't
> > gone to zero because there are objects (which happen to be
> > inside it) which still reference it.
> 
> Thanks for spelling this out.  I had, however, already read about
> this issue.  My objects will be explicitly collected (at least,
> my intent is to).  Err, rather, I assume that 'sys.exc_traceback
> = None' will do this after the contained have lived their life? 
> I poorly expressed my self here as I didn't believe it to be
> central to my point of contention. Thanks.  I'll pay more
> attention next time!  :) 

I'm not clear on what you're saying, so I'll spell things out:

The 'sys.exc_traceback = None' trick will allow the locals from 
whence the exception was thrown to be collected.

You can break a container / contained cycle from either side - 
either explicitly delete the object from the container, or 
explicitly set the object's reference to the container to None, 
or both. It all depends on the respective desired lifetimes of 
the objects / container. To be thorough, you would have a 
release(self) method on the object, *and* do container[key] = 
None.
 
> > 
> > [subclassing]
> > 
> > > Obviously, I want to keep all of the existing engine's
> > > functionality, but simply extend it with the turbo's boost
> > > methods.  As I understand it, you can't do this?!?!?  If I
> > > understand you correctly, I have to re-implement engine's
> > > constructor and extend it in the turboEngine's constructor.
> > 
> > You have to call the base class's __init__ explicitly. __init__
> > isn't actually a "constructor", it is an "initializer". In
> > other words, "self" is the real, final thing when __init__
> > runs; you just get to set up it's state, not influence it's
> > construction.
> 
> Hmmm.  I'll try again.  I guess it was something I was doing
> wrong.  I was getting an unbound method error.  

You need to say:
  base.__init__(self, arg, ...)

because "base.__init__" is an unbound method (you're 
referencing it through the class, not an instance). You 
undoubtedly omitted the "self".

> As for the
> constructor/initializer reference.  To me, it looks like python's
> equivalent to a C++ constructor, so that's what I called it.  Is
> "initializer" the correct terminology for python?

"Constructor" would be the more common term, but you need 
to realize that it's not the same as a C++ constructor ;-).

> > 
> > There's nothing automatic about __init__, which is why mixins
> > are easy and useful in Python (but rarely so elsewhere).
> 
> Can you expand on this a bit?  Everything I've seen suggests that
> __init__ is automatic.  If you can point me to some read'n here,
> that would be great.  

The instance construction mechanism calls the instance's 
__init__ (if it has one) as it's final act, but there's nothing like 
the C++ mechanism that goes looking for appropriate base 
class constructors. If you want to call them, *you* have to do 
it, (so most people call the immediate superclass's __init__ ).

You can learn the gory details by reading the stuff in 
Demo/metaclasses, but wear a helmet so you don't make a 
mess of the walls. Better yet, put a mark on your calendar to 
look at this six months from now.

> I'm also not sure how a mixin would help
> here, other than to provide a method that accepts the reference
> to the container. Obviously, you've pushed me to something that
> "feels" better, but isn't exactly what I was hoping for.  Still,
> I say thanks!

I've completely lost track of what your problem was ;-). Just 
saying that in Python, mixins are easy and natural; and this is 
largely because instance construction and instance 
initialization aren't confounded.
 


- Gordon




More information about the Python-list mailing list