[Python-Dev] How to suppress instance __dict__?

Alex Martelli aleax at aleax.it
Tue Mar 25 05:52:29 EST 2003


<posted & mailed>

David Abrahams wrote:

> "Delaney, Timothy C (Timothy)" <tdelaney at avaya.com> writes:
> 
>> Because most of the time we want to work with fully-constructed
>> objects. You can't use overridden methods in a constructor - only
>> from an initialiser.
> 
> Even if that were true, it's seldom needed (only comes up rarely in
> C++ where you can't do that) and often incorrect in any case because
> the derived class isn't constructed yet.

I think you're dismissing the issue a tad too glibly.  In C++, I
often found myself needing the "two-phase initialization" pattern:
a costructor that did the VERY MINIMUM needed to ensure some very
fundamental invariants on the object -- then, a framework would
ensure that an ordinary virtual method "initialize" got called
to give the object a chance to do substantial initialization work
before the object got totally hooked up to the framework and
started being used in earnest.  The key issue was often that, for
a constructor, you could never be sure if the object WAS fully
constructed (or if you were in a base class) -- no such problems
with 'initialize', where you could rest serene that you WERE
executing in the "leaf class", with a fully constructed object,
period.

For example say that the purpose of my class is modeling a
window object in some underlying windowing system.  The actual
window object must be costructed only once, and it must be
constructed with detailed parameters as determined/overridden
by the leaf class -- so no constructor of a class that might
possibly be used as a BASE class dare invoke the underlying
window system's "create window" operation, because the ctor
of more-derived classes haven't been run yet so it's uncertain
which parameters should in fact be used for that operation.
Whence, the need for two-phase init -- the underlying window 
is constructed in the 'initialize' (second phase) so the leaf
class has full power to control window creation parameters.

Classes modeling connections to external entities of many
kinds often have similar issues -- i.e. from this POV there
is no necessary difference between "creating the underlying
window object" and "opening the connection to the database",
say -- in both cases there are creation/opening parameters
and the potential need to override them, etc, etc.

I can find many more use cases of "two-phase init", but this
by itself should already suffice to explain that it's
anything but "seldom needed"... in C++.  ctor's just labor
under too many constraints to make them fully satisfactory
for all cases of initialization needs.


How this translates to Python -- I'm not sure.  The __new__
constructor, at first blush, would seem to be just as flexible
as the __init__ initializer.  However, some issues are
apparent.  It's easy for an __init__ to delegate to that
of a superclass; it's NOT easy to see how similar delegation
is supposed to take place for __new__ -- just as an example.
It's certainly possible to arrange for the latter, mind you:
__new__ does have a cls parameter so it may costruct objects
of different classes from the one I'm coding it in -- so if
everything is coded with extreme care perhaps there are no
real obstacle cases.  But consider MULTIPLE inheritance --
how would you arrange for THAT...?  I.e.:

class Ba1(object):
    def __init__(self):
        self.a1 = 23
        super(Ba1, self).__init__()

class Ba2(object):
    def __init__(self):
        self.a2 = 45
        super(Ba2, self).__init__()

class Der(Ba1, Ba2):
    def __init__(self):
        super(Der, self).__init__()
        self.b = 67

Using __new__ instead of __init__, how does class Der,
derived from two independently coded bases, ensure all
initialization done by the bases (here symbolically
represented by mere attribute setting) is properly 
performed on the new object of class Der being created,
before finishing it up as it likes (here with just
yet another attribute setting)?


Alex






More information about the Python-list mailing list