python中的抽象方法和mixin



我想提交一个我在工作中经常看到的python代码模式,我对它不满意,我想要一个更好的解决方案。

今天的内容如下:

class AbstractClass(object):
    ....
    def method1(self,...)
       raise NotImplementedError
    ...
class FirstImplementationMixin(object)
    def method1(self,....) 
       ...
class SecondImplementationMixin(object)
    def method1(self...)
       ....
class InstanciatedClass1(FirstImplementationMixin, AbstractClass)
    ....
class InstanciatedClass2(SecondImplementationMixin, AbstractClass)
    ....

你明白了吗?我必须在列表的第一个位置添加mixin我不喜欢这个解决方案。如果我们在第二个位置添加它,解释器将使用AbstractClass。

在这种平凡的情况下,用中间类替换mixin是可能的,但在已经有基类的复杂继承情况下,解决方案可能不明显。

你认为最好的设计模式是什么?

嗯,正如我在评论中指出的,这就是Python的工作方式,我不认为改变它是一个好主意。

然而,元类可以拯救我们!
您可以创建自己的元类,并使其尽可能复杂。这里我将向您展示一个非常基本的示例。

def mixed(name, bases, dct):
    return type(name, bases[1:] + (bases[0],), dct)

它只是将第一个基类移到最后,所以现在您将实际的基类放在前面,然后是所有的mixin。这意味着您只能使用一个基类。你可以通过一些约定来解除这个限制,例如,你会先列出基类,然后是None,然后是mixins;元类将查找此None并相应地对元组重新排序。

class MixinA:
    pass
class MixinB:
    pass
class Base(object):
    pass
class Test(Base, MixinA, MixinB):
    __metaclass__ = mixed
>>> Test.__mro__
                 >
(<class '__main__.Test'>,
 <class __main__.MixinA at 0x6f8850db48>,
 <class __main__.MixinB at 0x6f8850dae0>,
 <class '__main__.Base'>,
 <type 'object'>)

当然,您不会每次都指定__metaclass__,因为用于选择元类的规则。您可能会将__metaclass__设置在模块级别上,或者可能在您的mixins中。这是你的选择,任何适合你的代码结构。

相关内容

  • 没有找到相关文章

最新更新