请考虑以下代码实现一个简单的MixIn
:
class Story(object):
def __init__(self, name, content):
self.name = name
self.content = content
class StoryHTMLMixin(object):
def render(self):
return ("<html><title>%s</title>"
"<body>%s</body></html>"
% (self.name, self.content))
def MixIn(TargetClass, MixInClass):
if MixInClass not in TargetClass.__bases__:
TargetClass.__bases__ += (MixInClass,)
if __name__ == "__main__":
my_story = Story("My Life", "<p>Is good.</p>")
# plug-in the MixIn here
MixIn(Story, StoryHTMLMixin)
# now I can render the story as HTML
print my_story.render()
运行main
导致如下错误:
TypeError: Cannot create a consistent method resolution
order (MRO) for bases object, StoryHTMLMixin
问题是Story
和StoryHTMLMixin
都源自object
,于是钻石问题就出现了。
解决方案是简单地制作StoryHTMLMixin
一个旧式类,即删除继承自object
,因此,将类的定义更改StoryHTMLMixin
为:
class StoryHTMLMixin:
def render(self):
return ("<html><title>%s</title>"
"<body>%s</body></html>"
% (self.name, self.content))
运行时导致以下结果main
:
<html><title>My Life</title><body><p>Is good.</p></body></html>
我不喜欢使用旧式类,所以我的问题是:
这是在 Python 中处理此问题的正确方法,还是有更好的方法?
编辑:
我看到最新的 Python 源代码UserDict
中的类定义了一个使用旧样式类的 MixIn(如我的示例中所示)。
正如所有人的建议,我可能会在不使用 MixIns 的情况下重新定义我想要获得的功能(即在运行时绑定方法)。然而,重点仍然存在——这是唯一一个在不求助于重新实现或回退到旧式类的情况下无法解决 MRO 的用例吗?