gpt4 book ai didi

python - Python中使用MixIns时出现菱形问题

转载 作者:太空狗 更新时间:2023-10-29 22:08:28 27 4
gpt4 key购买 nike

请考虑以下实现简单 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

问题是 StoryStoryHTMLMixin 都是从 object 派生的,并且 diamond problem出现。

解决方案很简单,就是让 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 中处理这个问题的正确方法,还是有更好的方法?

编辑:

我在 latest Python source 中看到类 UserDict定义一个采用旧式类的 MixIn(如我的示例所示)。

正如大家所建议的,我可能会在不使用 MixIns 的情况下重新定义我想要获得的功能(即,在运行时绑定(bind)方法)。然而,问题仍然存在——这是唯一一个在不诉诸重新实现或回退到旧式类的情况下无法解决与 MRO 混淆的用例吗?

最佳答案

为什么不直接使用 mixin 而不是在 mro 中进行修改?

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))

class StoryHTML(Story, StoryHTMLMixin):
pass


print StoryHTML('asd','asdf').render() # works just fine

如果您真的、真的、真的想在类上添加额外的方法,那不是什么大问题。好吧,除了这是邪恶和不好的做法。无论如何,您可以随时更改类(class):

# first, the story
x = Story('asd','asdf')

# changes a class object
def stick_methods_to_class( cls, *methods):
for m in methods:
setattr(cls, m.__name__, m)

# a bare method to glue on
def render(self):
return ("<html><title>%s</title>"
"<body>%s</body></html>"
% (self.name, self.content))

# change the class object
stick_methods_to_class(Story, render)

print x.render()

但最后,问题仍然存在:为什么类突然要增加额外的方法?这就是恐怖电影的素材 ;-)

关于python - Python中使用MixIns时出现菱形问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4514803/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com