Please consider the following code implementing a simple 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()
Running main
leads to the following error:
TypeError: Cannot create a consistent method resolution
order (MRO) for bases object, StoryHTMLMixin
The problem is that both Story
and StoryHTMLMixin
are derived from object
, and the diamond problem arises.
The solution is simply to make StoryHTMLMixin
an old-style class, i.e., remove the inheritance from object
, thus, changing the definition of the class StoryHTMLMixin
to:
class StoryHTMLMixin:
def render(self):
return ("<html><title>%s</title>"
"<body>%s</body></html>"
% (self.name, self.content))
leads to the following result when running main
:
<html><title>My Life</title><body><p>Is good.</p></body></html>
I don't like having to use old style classes, so my question is:
Is this the correct way to handle this problem in Python, or is there a better way?
Edit:
I see that the class UserDict
in the latest Python source defines a MixIn resorting to the old style classes (as presented in my example).
As recommended by all, I may resort to redefining the functionality that I want to attain (namely, the binding of methods at run time) without using MixIns. However, the point still remains - is this the only use case where messing with the MRO is unsolvable without resorting to reimplementation or falling back to old-style classes?