__init__ is the initialiser

Gregory Ewing greg.ewing at canterbury.ac.nz
Mon Feb 3 18:47:12 EST 2014


Steven D'Aprano wrote:
> # --- Untested ---
> # Automatically call each __new__ constructor method, starting from
> # the most fundamental (object) and ending with the current class.
> stack = []
> for c in cls.__mro__:
>     if hasattr(c, '__new__'):
>         stack.append(c.__new__)
> while stack:
>     stack.pop()(*args)

That sort of thing doesn't allow for passing different
arguments to the base __new__.

Also remember that in Python, __new__ isn't actually
required to call a matching base version at all -- it's
legal to do something quite different, such as returning
a cached instance or instantiating a different type of
object altogether.

> What I meant by backwards compatibility is that prior to the introduction 
> of new-style classes, you couldn't override __new__, only __init__. So if 
> you had a classic class, you'd have to receive the instance:
> 
> class Classic:
>     def __init__(self, *args):
>         ...
> 
> but for new-style classes, you'd receive the class:
> 
> class Newstyle(object):
>     def __init__(cls, *args):
>         ...

What I'm saying is that even if all classes had been
new-style from the beginning, it's by no means certain that
Guido wouldn't have come up with the __new__/__init__
system anyway, because of the flexibility it provides.

Python isn't the only language to do something like that.
In Objective-C, the basic pattern for instantiating an
object goes like

    [[SomeClass alloc] init: args]

where 'alloc' allocates memory for the object and
'init:' or some variation thereof initialises it.

-- 
Greg



More information about the Python-list mailing list