no return values for __init__ ??

Martin Pool martinp at mincom.com
Wed Jan 12 02:21:17 EST 2000


Helge Hess wrote:

> I can't see on what you base this statement on ?! This capability
> generalizes, not specializes, the environment - which leads me to the
> assumption that the *current* state will make programmers wonder.
> 
> Until now I haven't heard a reason against this 'feature' which I can
> follow. I guess that it is just a matter of taste.

Here's my argument: one of Python's strengths is that despite being
quite flexible, it also generally produces code which is transparent to
the reader.  Factory methods seem to me like they would solve your
problem and are clearer than constructors that don't really construct.  

If I write

  import mangler
  o = mangler.NetworkMangler(22)

and know that NetworkMangler is a class, then I can feel pretty sure
that I've just created a new instance.  Of course that could be a method
call, or indeed any other kind of callable thing, but in general it's
pretty clear.  

If that class wants to offer a singleton or an instance from a pool then
the interface ought to be like this:

  o = mangler.mangler(22)

which makes it clearer that I'm not necessarily getting a new instance. 
This idiom seems pretty well established.

It seems to me that one point in favour of your proposal is that it
hides from the caller the details of whether they're getting a new
instance or not.  I don't remember ever caring in Python about whether
`a is b' rather than `a == b' (though it often happens in Java), but
still it seems like something the client ought to be allowed to rely
on.  I guess it also prevents callers from accidentally creating new
instances when they're not supposed to, though the flavour of Python
seems to be that the documentation should just say "don't do that."

My main criticism is that it seems to lead off down the C++ path of
adding individually harmless features that in sum mean it's hard to tell
what to tell what any single statement does.

Aahz wrote:
>  __init__ gets called by the constructor to
> ensure that the returned object is in a valid state, and it seems
> reasonable to me that __init__ cannot substitute a different object for
> the constructor to return.

What's supposed to happen if somebody calls super.__init__(self)?  Does
all the code that does that have to check if the superclass returned
something else?  What if the subclass already started initializing
things before it called the superconstructor.  What if in a
multiply-inherited class the two constructors _both_ wanted to return
different objects?  (Python seems happy to arbitrarily resolve conflicts
like this, but still it seems bad to introduce them when they're not
necessary.)

Helge wrote:

> a = MyString(data="sadfjsadf", encoding='utf8')

Why not 

  a = mystring(data='sadlksad", encoding="utf8")

and that can return any instance of MyString that it likes.  (Hmm, maybe
I've been in Java for too long and am too used to using factories to
work around limitations.)

As a humble programmer I'm very happy that Guido adds features
cautiously.

-- 
Martin

`illegal copying' as opposed to `piracy'. ie, changing ones and
zeroes as opposed to pillaging, rape and murder on the high seas.
				-- aj



More information about the Python-list mailing list