从Python中的常用函数中提取mixin

时间:2014-04-17 10:20:41

标签: python oop inheritance mixins

考虑两个类,每个类都有一个现有的共享函数,但是有单独的继承路径:

class ClazzA(SuperClazzX):
    def foo(self):
        return goo(super(SuperClazzX, self).foo())

class ClazzB(SuperClazzY):
    def foo(self):
        return goo(super(SuperClazzY, self).foo())

foo显然是一个可以提取到mixin的常用函数,这样做的正确方法是什么,即使要调用不同的超级foo,功能仍然存在?

编辑:我删除了另一个混音,这让人感到困惑和无关紧要。

1 个答案:

答案 0 :(得分:1)

编辑:更简单的代码

Mixin可以访问(未来)子类的其他基础,此处C::Mixin::foo可以访问C的其他基础,即C::Base::fooAuthoritative explanation here

class Base(object):  # must be new-style class in py 2.x
    def foo(self):
        print "base foo called"

class Mixin(object):
    def foo(self):
        rv = super(Mixin, self).foo()  # call actual implementation
        # use rv

class C(Mixin, Base):
    pass

C().foo()
base foo called

这是做什么的:

  • selfC的实例,它的__mro__是(Mixin,Base)
  • 当Mixin调用super(Mixin, self)时,生成的对象保留基数(Base,)
  • 解析.foo属性时,此对象在Base
  • 中找到它
  • 因此使用原始Base.foo
  • 调用self

如果您希望自定义控制实施,您可以访问自己的基础,例如:

class Foo(...):
    def foo(self):
        print self.__class__.__bases__

你的mixin看起来像这样,超级手动的方法:

class Mixin(object):
    def foo(self):
        assert self.__class__ is not Mixin  # no point calling directly
        # find the other base
        other = [b for b in self.__class__.__bases__ if b is not Mixin]
        # what to do if there's more than 1 real base?
        # pick base explicitly
        base = other[1]
        # call it, 
        return something(base.foo(self, some_args))