抽象类 + 混合+ python中的多重继承

发布于 2024-07-18 16:43:16 字数 596 浏览 9 评论 0原文

所以,我认为代码可能比语言更能解释我想要做的事情,所以这里是:

import abc

class foo(object):
    __metaclass__ = abc.ABCMeta
    @abc.abstractmethod
    def bar(self):
        pass


class bar_for_foo_mixin(object):
    def bar(self):
        print "This should satisfy the abstract method requirement"


class myfoo(foo, bar_for_foo_mixin):
    def __init__(self):
        print "myfoo __init__ called"
        self.bar()

obj = myfoo()

结果:

TypeError: Can't instantiate abstract class myfoo with abstract methods bar

我试图让 mixin 类满足抽象/接口类的要求。 我缺少什么?

So, I think the code probably explains what I'm trying to do better than I can in words, so here goes:

import abc

class foo(object):
    __metaclass__ = abc.ABCMeta
    @abc.abstractmethod
    def bar(self):
        pass


class bar_for_foo_mixin(object):
    def bar(self):
        print "This should satisfy the abstract method requirement"


class myfoo(foo, bar_for_foo_mixin):
    def __init__(self):
        print "myfoo __init__ called"
        self.bar()

obj = myfoo()

The result:

TypeError: Can't instantiate abstract class myfoo with abstract methods bar

I'm trying to get the mixin class to satisfy the requirements of the abstract/interface class. What am I missing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我的奇迹 2024-07-25 16:43:16

继承不应该反过来吗? 在 MRO 中,foo 目前位于 bar_for_foo_mixin 之前,然后正确地抱怨。 使用 class myfoo(bar_for_foo_mixin, foo) 它应该可以工作。

我不确定你的班级设计是否是正确的方法。 由于您使用 mixin 来实现 bar ,因此最好不要从 foo 派生,而只需将其注册到 'foo' 类(即 foo.register(myfoo)) 。 但这只是我的直觉。

为了完整起见,这里是ABC 文档

Shouldn't the inheritance be the other way round? In the MRO foo currently comes before bar_for_foo_mixin, and then rightfully complains. With class myfoo(bar_for_foo_mixin, foo) it should work.

And I am not sure if your class design is the right way to do it. Since you use a mixin for implementing bar it might be better not to derive from foo and just register it with the 'foo' class (i.e. foo.register(myfoo)). But this is just my gut feeling.

For completeness, here is the documentation for ABCs.

慵挽 2024-07-25 16:43:16

我认为(在类似情况下测试)反转基类是有效的:

class myfoo(bar_for_foo_mixin, foo):
    def __init__(self):
        print "myfoo __init__ called"
        self.bar()

所以在 mro() 中,它会在找到抽象版本之前找到 bar() 的具体版本。 不知道这是否真的是在后台发生的事情。

干杯,Lars

PS:在 python 2.7 中工作的代码(python 3 有不同的设置元类的方法)是:

class A(object):
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def do(self):
        pass

class B(object):
    def do(self):
        print "do"

class C(B, A):
    pass

c = C()

i think (tested in similar case) that reversing the baseclasses works:

class myfoo(bar_for_foo_mixin, foo):
    def __init__(self):
        print "myfoo __init__ called"
        self.bar()

so in the mro() it would find a concrete version of bar() before it finds the abstract one. No idea if this is actually what happens in the background though.

Cheers, Lars

PS: the code that worked in python 2.7 (python 3 has a different way to set metaclasses) was:

class A(object):
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def do(self):
        pass

class B(object):
    def do(self):
        print "do"

class C(B, A):
    pass

c = C()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文