単純なものを実装する次のコードを検討してください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を定義していることがわかります。
すべての人が推奨しているように、MixInを使用せずに、実現したい機能(つまり、実行時のメソッドのバインド)を再定義することに頼ることができます。ただし、要点はまだ残っています。これは、再実装に頼ったり、古いスタイルのクラスにフォールバックしたりせずにMROをいじることができない唯一のユースケースですか?