2

我想提交一个我经常在我的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.method1 并因此引发异常。

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

对你来说最好的设计模式是什么?

4

1 回答 1

1

好吧,正如我在评论中指出的那样,这正是 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__在模块级别设置,或者可能在您的 mixin 中设置。这是您的选择,无论哪种方式更适合您的代码结构。

于 2013-06-05T17:44:33.417 回答