Python MixIn 标准
所以我正在编写一些代码,最近遇到需要实现一些 mixins 的情况。我的问题是,设计混合的正确方法是什么?我将使用下面的示例代码来说明我的确切查询。
class Projectile(Movable, Rotatable, Bounded):
'''A projectile.'''
def __init__(self, bounds, position=(0, 0), heading=0.0):
Movable.__init__(self)
Rotatable.__init__(self, heading)
Bounded.__init__(self, bounds)
self.position = Vector(position)
def update(self, dt=1.0):
'''Update the state of the object.'''
scalar = self.velocity
heading = math.radians(self.heading)
direction = Vector([math.sin(heading), math.cos(heading)])
self.position += scalar * dt * direction
Bounded.update(self)
class Bounded(object):
'''A mix-in for bounded objects.'''
def __init__(self, bounds):
self.bounds = bounds
def update(self):
if not self.bounds.contains(self.rect):
while self.rect.top > self.bounds.top:
self.rect.centery += 1
while self.rect.bottom < self.bounds.bottom:
self.rect.centery += 1
while self.rect.left < self.bounds.left:
self.rect.centerx += 1
while self.rect.right > self.bounds.right:
self.rect.centerx -= 1
基本上,我想知道,混合是否有点像 Java 接口,其中存在一种(在 Python 的情况下是隐式的)契约,如果希望使用代码,则必须定义某些变量/函数(与框架不同) ,或者它更像我上面编写的代码,其中每个混合都必须显式初始化?
So I'm writing some code and have recently come across the need to implement a few mixins. My question is, what is the proper way to design a mix-in? I'll use the example code below to illustrate my exact query.
class Projectile(Movable, Rotatable, Bounded):
'''A projectile.'''
def __init__(self, bounds, position=(0, 0), heading=0.0):
Movable.__init__(self)
Rotatable.__init__(self, heading)
Bounded.__init__(self, bounds)
self.position = Vector(position)
def update(self, dt=1.0):
'''Update the state of the object.'''
scalar = self.velocity
heading = math.radians(self.heading)
direction = Vector([math.sin(heading), math.cos(heading)])
self.position += scalar * dt * direction
Bounded.update(self)
class Bounded(object):
'''A mix-in for bounded objects.'''
def __init__(self, bounds):
self.bounds = bounds
def update(self):
if not self.bounds.contains(self.rect):
while self.rect.top > self.bounds.top:
self.rect.centery += 1
while self.rect.bottom < self.bounds.bottom:
self.rect.centery += 1
while self.rect.left < self.bounds.left:
self.rect.centerx += 1
while self.rect.right > self.bounds.right:
self.rect.centerx -= 1
Basically, I'm wondering, are mix-ins sort of like Java interfaces where there is a sort of (in Python's case implicit) contract that if one wishes to use the code one must define certain variables / functions (not unlike a framework), or is it more like the code I've written above, where each mix-in must be initialized explicitly?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以在 Python 中同时拥有这两种行为。您可以通过使用抽象基类或通过在虚拟函数中引发 NotImplementedError 来强制重新实现。
如果 init 在家长的课程中很重要,那么您必须调用它们。正如 eryksun 所说,使用 super 内置函数来调用父级的初始化器(这样,给定类的初始化器只会被调用一次)。
结论:取决于你拥有什么。在您的情况下,您必须调用 init,并且应该使用
super
。You can have both behavior in Python. You can force the reimplementation by using Abstract Base Classes, or by raising NotImplementedError in virtual functions.
If init are important in parent's classes, then you have to call them. As eryksun said, use the
super
builtin function to call the parent's initializers (this way, an initializer for a given class will only be called once).Conclusion: depends on what you have. In your case, you have to call init, and you should use
super
.