initializing mutable class attributes

Dan Perl dperl at rogers.com
Wed Sep 1 10:54:06 EDT 2004


"Alex Martelli" <aleaxit at yahoo.com> wrote in message
news:1gjfkp7.aepmjg11ubf2rN%aleaxit at yahoo.com...
>    ...
> > though that I do not accept "explicit is better than implicit" as an
> > absolute truth.  [That's like when someone told me once with pride: "I
> > always design bottom-up."]  Applying a principle like that CONSISTENTLY
in
> > the design of a language can make a very good language.  On the other
hand,
> > I can imagine there can be very good languages, with their own uses and
> > advantages, if the reverse principle were consistently used.
>
> Perhaps, but from my experience with languages which consistently try to
> double-guess programmer intent and "do what's right" implicitly based on
> context, it doesn't work -- I'm thinking of PL/I, C++, Perl.  They're
> all big languages, so perfect consistency is impossible, of course.  But
> even small languages grow, if they're successful.  Do you have specific
> examples in mind of very good languages based on "implicit is better
> than explicit"?

No, I do not have an example, but I still stand by my comment.  Maybe it's
just impossible to use the principle "implicit is better than explicit"
consistently because you need at least something explicit.

> > You may see in another message I posted in this thread that I ended up
> > giving an answer to my own question (the 'WHY' question).  Here is my
reason
> > for that 'WHY'.  Python does not have method overloading (and I am ok
with
> > that, because it comes with the dynamic typing), so you cannot have a
> > default constructor and a non-default one at the same time.  C++ and
Java
>
> Not with the same name.  You can have all alternative constructors you
> want if you give them different names -- that's a popular use of
> classmethod (in Python as well as in Smalltalk, though there are
> differences between the two, of course).  Alternative names are more
> powerful than any overloading based on type could possibly be.
> Consider:

We may have a disagreement in terminology, but I was using "overloading" in
the C++/Java sense, which means strictly samename, different signatures.

> > have overloading and then can also mandate a default constructor for a
> > parent class, even if it's empty because you actually use only a
non-default
> > constructor for that class.  Python cannot request that you also
implement a
> > default __init__ when you need a non-default one.  There would be the
> > possibility of adding another special method, but there's already
__init__
> > and __new__, so that would be too confusing.
>
> Java and C++ _could_ mandate a default ctor, but they don't -- it would
> be a very bad design decision for them to do so, and their designers
> aren't THAT bad:-).  It's perfectly possible to have a class that just
> CANNOT be constructed without some specific arguments.

Try this C++ code:
    #include <iostream>
    class Class1 {
    public:
        Class1(int arg )
            {
            std::cout << "Class1 Constructor"  << std::endl;
            }
    };
    class Class2 : public Class1 {
    public:
        Class2(int arg)
            {
            std::cout << "Class2 Constructor"  << std::endl;
            }
    };
    int main(int argc, char **argv)
        {
        Class2 c2 = Class2(9);
        }

The compiler (I tried gcc) will give an error that the Class1::CLass1( )
constructor is missing.  Without the non-default Class1 constructor, the
compiler would have created a default constructor, IMPLICITLY.  Note that
even C++ chooses not to create the implicit, default, constructor anymore if
you have a non-default constructor.  You have to do it explicitly, even if
it's an empty one.

Anyway, in C++, if I write a library with a class like Class1, I can create
a default constructor to initialize all the members with default values if
there is no need for non-default values.  C++ gives me that possibility.  A
user of my library (who will never know me) can use this library and does
not need to know anything about the Class1 constructor.  This is consistent
with the principle of encapsulation, so subclasses don't need to know
anything about how the superclass is implemented.

Not in Python.  A user of my library has to invoke the parent's class
__init__ in their own __init__.  What happens if, in a future release, I get
rid of the __init__ in the parent class?  Or the other way around.  An early
release does not have a parent __init__, the users don't invoke it because
they can't, and then, in a future release, I add the parent __init__ because
I added some attributes.  It breaks all the users' code.  This is poor
encapsulation.

I think this IS a case where "implicit is better than explicit".

Dan





More information about the Python-list mailing list