Вызов `super()` в родительском классе
Я читаю Raymond Hettinger Pythons super() считается супер! О странице в этом примере:
class Shape:
def __init__(self, shapename, **kwds):
self.shapename = shapename
super().__init__(**kwds)
class ColoredShape(Shape):
def __init__(self, color, **kwds):
self.color = color
super().__init__(**kwds)
cs = ColoredShape(color='red', shapename='circle')
Зачем нужно звонить super()
в Shape
здесь? Я понимаю, что это вызывает object.__init__(**kwds)
, поскольку Shape
неявно наследует от object
.
Даже без этого утверждения мы уже
- установлен
shapename
уже в родительском __init__
,
- установил дочерний класс
color
в явном переопределении метода,
- затем вызывается родительский
__init__
с super()
в ColoredShape
.
Насколько я могу судить, отбрасывание этой строки приводит к такому же поведению и функциональности:
class Shape: # (object)
def __init__(self, shapename, **kwds):
self.shapename = shapename
# super().__init__(**kwds)
class ColoredShape(Shape):
def __init__(self, color, **kwds):
self.color = color
super().__init__(**kwds)
def check(self):
print(self.color)
print(self.shapename)
cs = ColoredShape(color='red', shapename='circle')
cs.check()
# red
# circle
В чем цель super()
внутри Shape
здесь?
Ответы
Ответ 1
Я вижу, что @user2357112 уже предоставил правильный ответ. Я работал над примером, который, хотя я бы ушел, потому что это довольно много, что описывает user2357112. Рассмотрим класс mixin следующим образом:
class PositionMixin:
def __init__(self, x=0, y=0, **kwds):
super().__init__(**kwds)
self.x = x
self.y = y
Скажем, вы примените это к классу ColoredShape
:
class ColoredShape(Shape, PositionMixin):
def __init__(self, color, **kwds):
self.color = color
super().__init__(**kwds)
Если Shape
не вызывает super.__init__
, то когда вы это сделаете:
myshape = ColoredShape('red', shapename='circle', x=1, y=1)
print(myshape.x, myshape.y)
Вы получаете:
Traceback (most recent call last):
File "supertest.py", line 18, in <module>
print (myshape.x, myshape.y)
AttributeError: 'ColoredShape' object has no attribute 'x'
Вызов super.__init__
в форме необходим для вызова метода __init__
на PositionMixin
.
Ответ 2
Точка - совместное множественное наследование. На самом деле точка всей статьи - это совместное множественное наследование.
Вы смотрите Shape
, и вы не видите никаких родителей помимо object
. Конечно, но это не значит, что на MRO после Shape
нет ни одного брата или чего-либо еще на MRO. super()
относится не только к суперклассам; он ищет следующую реализацию метода в порядок разрешения метода. Например, один из более поздних классов в статье -
class MovableColoredShape(ColoredShape, MoveableAdapter):
pass
В этом случае Shape.__init__
необходимо вызвать super().__init__
или MoveableAdapter.__init__
, и все дальнейшие вызовы __init__
будут пропущены.