Why doesn't Python call instance method __init__() on instance creation but calls class-provided __init__() instead?

instances, methods, object, python

Solution

Special methods on new-style classes are looked up on the instance's type, not on the instance itself. This is documented behaviour:

For new-style classes, implicit invocations of special methods are only guaranteed to work correctly if defined on an object’s type, not in the object’s instance dictionary. That behaviour is the reason why the following code raises an exception (unlike the equivalent example with old-style classes):

>>> class C(object):
...     pass
...
>>> c = C()
>>> c.__len__ = lambda: 5
>>> len(c)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: object of type 'C' has no len()

Problem

I'm overring the `__new__()` method of a class to return a class instance which has a specific `__init__()` set. Python seems to call the class-provided `__init__()` method instead of the instance-specific method, although the Python documentation at http://docs.python.org/reference/datamodel.html says: Typical implementations create a new instance of the class by invoking the superclass’s __new__() method using super(currentclass, cls).__new__(cls[, ...]) with appropriate arguments and then modifying the newly-created instance as necessary before returning it. If __new__() returns an instance of cls, then the new instance’s __init__() method will be invoked like __init__(self[, ...]), where self is the new instance and the remaining arguments are the same as were passed to __new__(). Here's my test code: ``` #!/usr/bin/env python import new def myinit(self, *args, **kwargs): print "myinit called, args = %s, kwargs = %s" % (args, kwargs) class myclass(object): def __new__(cls, *args, **kwargs): ret = object.__new__(cls) ret.__init__ = new.instancemethod(myinit, ret, cls) return ret def __init__(self, *args, **kwargs): print "myclass.__init__ called, self.__init__ is %s" % self.__init__ self.__init__(*args, **kwargs) a = myclass() ``` which outputs ``` $ python --version Python 2.6.6 $ ./mytest.py myclass.__init__ called, self.__init__ is <bound method myclass.myinit of <__main__.myclass object at 0x7fa72155c790>> myinit called, args = (), kwargs = {} ``` It seems the only way to get `myinit()` to run, is to call it explicitly as `self.__init__()` inside `myclass.__init__()`.

Original source