__init__ is not invoked
Oscar Benjamin
oscar.j.benjamin at gmail.com
Thu Sep 26 10:22:58 EDT 2019
On Thu, 26 Sep 2019 at 14:19, Peter Otten <__peter__ at web.de> wrote:
>
> __init__ is called only if __new__ returns an instance of ClassB:
>
> """
> /* If the returned object is not an instance of type,
> it won't be initialized. */
> if (!PyType_IsSubtype(Py_TYPE(obj), type))
> return obj;
>
> type = Py_TYPE(obj);
> if (type->tp_init != NULL) {
> int res = type->tp_init(obj, args, kwds);
> """
>
> https://github.com/python/cpython/blob/master/Objects/typeobject.c#L982
Interesting. I hadn't realised that was how it works. I tested with this:
"""
class A:
def __new__(cls, arg):
if arg == 'a':
return object.__new__(A)
elif arg == 'b':
return object.__new__(B)
elif arg == 'c':
return object.__new__(C)
elif arg == 'd':
return D('foo')
def __init__(self, arg):
print('A.__init__', arg)
class B:
def __init__(self, arg):
print('B.__init__', arg)
class C(A):
def __init__(self, arg):
print('C.__init__', arg)
class D(A):
def __new__(cls, arg):
return object.__new__(cls)
def __init__(self, arg):
print('D.__init__', arg)
A('a')
A('b')
A('c')
A('d')
"""
Output:
$ python tmp.py
A.__init__ a
C.__init__ c
D.__init__ foo
D.__init__ d
So B.__init__ is never called and D.__init__ is called twice. I wonder
if there is a sensible way of organising this. Certainly I've always
taken the approach that you either use __new__ or __init__ and don't
mix them up.
--
Oscar
More information about the Python-list
mailing list