__init__ is the initialiser

Chris Angelico rosuav at gmail.com
Fri Jan 31 23:35:17 EST 2014


On Sat, Feb 1, 2014 at 2:42 PM, Steven D'Aprano
<steve+comp.lang.python at pearwood.info> wrote:
> I've met people who have difficulty with OOP principles, at least at
> first. But once you understand the idea of objects, it isn't that hard to
> understand the idea that:
>
> - first, the object has to be created, or constructed, or allocated
>   if you will;
>
> - only then can it be initialised.
>
> Thus, two methods. __new__ constructs (creates, allocates) a new object;
> __init__ initialises it after the event.

Yes, but if you think in terms of abstractions, they're both just
steps in the conceptual process of "creating the object". If I ask GTK
to create me a Button, I don't care how many steps it has to go
through of allocating memory, allocating other resources, etc, etc,
etc. All I want is to be able to write:

foobar = Button("Foo Bar")

and, at the end of it, to have a Button that I can toss onto a window.
That's the job of a constructor - to give me an object in a state that
I can depend on. (And this is completely independent of language.
Modulo trivialities like semicolons, adorned names, etc, etc, I would
expect that this be valid in any object oriented GUI toolkit in any
object oriented language.)

The difference between __new__ and __init__ is important when you
write either method, but not when you use the class. It's like writing
other dunder methods. You care about the distinction between __add__
and __radd__ when you write the methods, but in all other code, all
that matters is that it does what you want:

three = Three()
four = three + 1
four == 1 + three

The two methods could have been done as a single method,
__construct__, in which you get passed a cls instead of a self, and
you call self=super().__construct__() and then initialize stuff. It
would then be obvious that this is "the constructor". So maybe it's
best to talk about the two methods collectively as "the constructor",
and then let people call the two parts whatever they will.

I do like the idea of calling __init__ the initializer. The downside
of calling __new__ the constructor is that it'll encourage C++ and
Java programmers to override it and get themselves confused, when
really they should have been writing __init__ and having an easy time
of it. So, current best suggestion is "allocator" for that? Not
entirely sure that's right, but it's not terrible. I'm +1 on __init__
being documented as the initializer, and +0 on "allocator" for
__new__.

ChrisA



More information about the Python-list mailing list