Please see the following code:
#! /usr/bin/env python3
class MyTupleT(tuple):
def __init__(self, contents):
tuple.__init__(contents)
self.len = len(contents)
class MyTupleS(tuple):
def __init__(self, contents):
super().__init__(contents)
self.len = len(contents)
t = MyTupleT([0, 1, 2])
print(t.len, t)
s = MyTupleS([0, 1, 2])
print(s.len, s)
The output is:
3 (0, 1, 2)
Traceback (most recent call last):
File "tuple_init.py", line 16, in <module>
s = MyTupleS([0, 1, 2])
File "tuple_init.py", line 10, in __init__
super().__init__(contents)
TypeError: object.__init__() takes no parameters
The docs say that super()
will:
Return a proxy object that delegates method calls to a parent or sibling class of type
IIUC here super()
is the same as super(MyTupleS, self)
. Now the docs further say that
The search order is same as that used by
getattr()
except that the type itself is skipped. The__mro__
attribute of the type lists the method resolution search order used by bothgetattr()
andsuper()
.
Ohkay but then:
$ MyTupleS.__mro__
(__main__.MyTupleS, tuple, object)
So the super()
line should first look within tuple
to find __init__
and tuple's __init__
can certainly take one parameter (other than self
of course) and is what is being called by the explicit tuple.__init__
line. So why doesn't the super().__init__
call work identical to that? Why is it trying to invoke object.__init__
and failing?
IIUC one should only need to explicitly specify the superclass when one is worried that the inheritance hierarchy can change in a "dynamic execution environment" (phrase from the docs) and wants the method of a particular superclass to be called. But this error effectively makes it mandatory for the superclass to be specified. Why?
NOTE: This is different from another similarly titled question.