So I was following Python’s Super Considered Harmful, and went to test out his examples.
However, Example 1-3, which is supposed to show the correct way of calling super when handling __init__ methods that expect different arguments, flat-out doesn’t work.
This is what I get:
~ $ python example1-3.py
MRO: ['E', 'C', 'A', 'D', 'B', 'object']
E arg= 10
C arg= 10
A
D arg= 10
B
Traceback (most recent call last):
File "Download/example1-3.py", line 27, in <module>
E(arg=10)
File "Download/example1-3.py", line 24, in __init__
super(E, self).__init__(arg, *args, **kwargs)
File "Download/example1-3.py", line 14, in __init__
super(C, self).__init__(arg, *args, **kwargs)
File "Download/example1-3.py", line 4, in __init__
super(A, self).__init__(*args, **kwargs)
File "Download/example1-3.py", line 19, in __init__
super(D, self).__init__(arg, *args, **kwargs)
File "Download/example1-3.py", line 9, in __init__
super(B, self).__init__(*args, **kwargs)
TypeError: object.__init__() takes no parameters
It seems that object itself violates one of the best practices mentioned in the document, which is that methods which use super must accept *args and **kwargs.
Now, obviously Mr. Knight expected his examples to work, so is this something that was changed in recent versions of Python? I checked 2.6 and 2.7, and it fails on both.
So what is the correct way to deal with this problem?
Sometimes two classes may have some parameter names in common. In that case, you can’t pop the key-value pairs off of
**kwargsor remove them from*args. Instead, you can define aBaseclass which unlikeobject, absorbs/ignores arguments:yields
Note that for this to work,
Basemust be the penultimate class in the MRO.