On Thu, 26 Sep 2019 at 14:19, Peter Otten <__pete...@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 -- https://mail.python.org/mailman/listinfo/python-list