- Expert Python Programming(Third Edition)
- Micha? Jaworski Tarek Ziadé
- 244字
- 2021-06-24 14:55:18
Mixing super and explicit class calls
In the following example, taken from James Knight's website (http://fuhm.net/super-harmful), a C class that calls initialization methods of its parent classes using the super().__init__() method will make the call to the B.__init__() class to be called twice:
class A: def __init__(self): print("A", end=" ") super().__init__() class B: def __init__(self): print("B", end=" ") super().__init__() class C(A, B): def __init__(self): print("C", end=" ") A.__init__(self) B.__init__(self)
Here is the output:
>>> print("MRO:", [x.__name__ for x in C.__mro__]) MRO: ['C', 'A', 'B', 'object'] >>> C() C A B B <__main__.C object at 0x0000000001217C50>
In the preceding transcript we see that initialization of class C invokes the B.__init__() method twice. To avoid such issues, super should be used in the whole class hierarchy. The problem is that sometimes, a part of such complex hierarchy may be located in a third-party code. Many other related pitfalls on the hierarchy calls introduced by multiple inheritances can be found on James's page.
Unfortunately, you cannot be sure that external packages use super() in their code. Whenever you need to subclass some third-party class, it is always a good approach to take a look inside its code and the code of other classes in the MRO. This may be tedious, but, as a bonus, you get some information about the quality of code provided by such a package and more understanding of its code. You may learn something new that way.