Proposal: default __init__

Rainer Deyke root at rainerdeyke.com
Wed Nov 15 14:35:59 EST 2000


"Andrew Dalke" <dalke at acm.org> wrote in message
news:8uu6i2$ho6$1 at slb6.atl.mindspring.net...
> Yes, but your argument is not very strong.  Python already creates quite
> a few special variables for every class, like __name__, __bases__, __doc__
> and __module__.  The "differently from ANY other class" boils down to
>
>   if not new_class.__bases__:
>     # set up a default __init__

If you want special rules for __init__, the same special rules must also
apply to __del__ for the same reasons.

> >Just do:
> >
> >class NoSpam:
> >    def spam(self):
> >        print "no spam here, please!"
> >
> >and then:
> >
> >class A1(NoSpam,A):
> >    pass
>
> Ahh, you want getattr(A1, "spam") to come from NoSpam but
> getattr(A1, "__init__") (and everything else) to come from A.
> My code makes this harder to do because now you need to do:
>
> class A1(NoSpam, A):
>   __init__ = A.__init__
>
> But then, your code will break unexpectedly if you decide to have
>
> class NoSpam:
>   def __init__(self, potted_meat = "spam"):
>     self.__potted_meat = potted_meat
>   def spam(self):
>     print "no %s here, please!" % self.__potted_meat

This won't happen if NoSpam is documented as a mix-in class without
__init__.

> whereas mine will not, because you will already have had to define
> which __init__ you want.

Actually it will.  Your assignment '__init__ = A.__init__' prevents any
NoSpam's __init__ from being called.  If NoSpam has an __init__, it must be
called or the resulting object may be broken.

Your proposal simply does not work well with multiple inheritance.

There are three types of classes: those with no superclass, those with one
superclass, and those with several superclasses.

Those with no superclasses: The default initialization behavior is to do no
initialization.  It would be better IMO if 'C.__init__' (where C is a class)
was redefined to return an unbound method that does the initialization of an
instance of C.  (Whether the automatically generated __init__ is generated
during C's initialization or on demand is a non-issue here.)

Those with one superclass: The default behavior is to use the initialization
mechanism of the superclass.  If __init__ is defined, it can (and normally
should) call the superclass initialization mechanism.

Those with more than one superclass: The current default behavior is to use
the initialization mechanism of the first superclass that defines __init__.
This is bad.  The default mechanism should be to initialize all of the
bases.  Unfortunately it is not clear what the default mechanism should do
when it receives arguments.  The easy solution here is here is to define the
default __init__ of such classes to take no arguments (except 'self').  If
somebody wants to write a class with multiple inheritance that takes
arguments in the constructor, they'll have to define the constructor
manually: explicit is better than implict.

Note that all of this also applies to __del__, except that __del__ normally
doesn't take argument except 'self' anyway.

Or we could just require all classes to define __init__ and __del__
explicitly, but I don't think anybody wants that.


--
Rainer Deyke (root at rainerdeyke.com)
Shareware computer games           -           http://rainerdeyke.com
"In ihren Reihen zu stehen heisst unter Feinden zu kaempfen" - Abigor





More information about the Python-list mailing list