在 parent class 中调用 `super()`
Calling `super()` in parent class
我正在阅读 Raymond Hettinger 的 Python’s super() considered 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')
这里为什么要在Shape
中调用super()
?我的理解是,这会调用 object.__init__(**kwds)
,因为 Shape
隐式继承自 object
。
即使没有那个声明,我们也已经
- 已在 parent 的
__init__
、 中建立 shapename
- 在显式方法覆盖中建立了 child class 的
color
,
- 然后在
ColoredShape
中使用 super()
调用了 parent 的 __init__
。
据我所知,删除这一行会产生相同的行为和功能:
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
这里 Shape
中的 super()
的目的是什么?
重点是协同多重继承。整篇文章的重点是协同多重继承,真的。
你看Shape
,除了object
,你没有看到任何parents。当然可以,但这并不意味着 Shape
之后 MRO 上没有任何兄弟姐妹或其他任何东西。 super()
不仅仅适用于 super类;它在 method resolution order 中搜索该方法的下一个实现。比如文章后面的一个类是
class MovableColoredShape(ColoredShape, MoveableAdapter):
pass
在这种情况下,Shape.__init__
需要调用 super().__init__
,或 MoveableAdapter.__init__
并且将跳过所有进一步的 __init__
调用。
我看到@user2357112 已经提供了正确答案。我正在研究一个示例,虽然我会离开这里,因为它几乎就是 user2357112 所描述的内容。考虑这样的 mixin class:
class PositionMixin:
def __init__(self, x=0, y=0, **kwds):
super().__init__(**kwds)
self.x = x
self.y = y
假设您将其应用到您的 ColoredShape
class:
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__
的调用是调用 PositionMixin
上的 __init__
方法所必需的。
我正在阅读 Raymond Hettinger 的 Python’s super() considered 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')
这里为什么要在Shape
中调用super()
?我的理解是,这会调用 object.__init__(**kwds)
,因为 Shape
隐式继承自 object
。
即使没有那个声明,我们也已经
- 已在 parent 的
__init__
、 中建立 - 在显式方法覆盖中建立了 child class 的
color
, - 然后在
ColoredShape
中使用super()
调用了 parent 的__init__
。
shapename
据我所知,删除这一行会产生相同的行为和功能:
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
这里 Shape
中的 super()
的目的是什么?
重点是协同多重继承。整篇文章的重点是协同多重继承,真的。
你看Shape
,除了object
,你没有看到任何parents。当然可以,但这并不意味着 Shape
之后 MRO 上没有任何兄弟姐妹或其他任何东西。 super()
不仅仅适用于 super类;它在 method resolution order 中搜索该方法的下一个实现。比如文章后面的一个类是
class MovableColoredShape(ColoredShape, MoveableAdapter):
pass
在这种情况下,Shape.__init__
需要调用 super().__init__
,或 MoveableAdapter.__init__
并且将跳过所有进一步的 __init__
调用。
我看到@user2357112 已经提供了正确答案。我正在研究一个示例,虽然我会离开这里,因为它几乎就是 user2357112 所描述的内容。考虑这样的 mixin class:
class PositionMixin:
def __init__(self, x=0, y=0, **kwds):
super().__init__(**kwds)
self.x = x
self.y = y
假设您将其应用到您的 ColoredShape
class:
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__
的调用是调用 PositionMixin
上的 __init__
方法所必需的。