Не могли бы вы объяснить мне следующее поведение? Мое понимание подклассов, вероятно, не полное.
A . Давайте иметь этот простой класс. Он принимает любые аргументы и ничего не делает.
class Base1:
def __new__(cls, *args):
return object.__new__(cls)
Его MRO: (<class '__main__.Base1'>, <class 'object'>)
. Поскольку Base1
не имеет своего собственного __init__
, поиск метода __init__
разрешается в родительский (то есть в __init__
объекта). Доказательство:
assert Base1.__init__ is object.__init__ # OK
Давайте вызовем __init__
вручную:
b = Base1(0,1,2)
print(b.__init__) # prints: <method-wrapper '__init__' of Base1 object at 0x7f46d588ea90>
b.__init__(0,1,2) # OK <--- init call A
B . Base2
похож на Base1
, но имеет свои __init__
:
class Base2:
def __new__(cls, *args):
return object.__new__(cls)
def __init__(self, *args):
print(super().__init__) # prints: <method-wrapper '__init__' of Base2 object at 0x7f69d053ab50>
super().__init__(*args) # FAILURE! <--- init call B
MRO выглядит очень похоже: (<class '__main__.Base2'>, <class 'object'>)
. Я предполагаю, что super().__init__
является родительским (то есть снова объектом) __init__
, но:
b = Base2(1,2,3):
приводит к:
File "test.py", line 18, in __init__
super().__init__(*args)
TypeError: object.__init__() takes exactly one argument (the instance to initialize)
Обратите внимание на сообщение TypeError
. Это __init__
претендует на звание object.__init__
.
Так почему же вызовы init A и B различаются?