Python mixin带有一个不能被覆盖的方法(默认情况下)



在Python中,我使用了一个框架,让我像这样挂钩到一个生命周期:

class MyView(BaseView):
    def pre_save(self):
        print "view presave"

我想写一个mixin在pre_save中做一些事情,但我已经有很多代码在很多类中使用pre_save如上所述,而不调用super()。如果我像这样添加mixin:

class MyMixin(object):
    def pre_save(self):
        print "mixin presave"
class MyView(MyMixin, BaseView):
    def pre_save(self):
        print "view presave"

它自然地覆盖mixin,并且只打印"view save"。是否有另一种更隐蔽的方式,我可以写MyMixin不强迫所有客户端视图记住调用super() ?

这个答案是一个概念证明,而不是一个建议。不要在生产代码中这样做。您将创建维护噩梦。我同意那些对你的问题的评论,唯一安全的方法是编辑派生类。

也就是说,使用元类在技术上是可行的。

def do_evil(self, method):
    print "doing evil"
    MyMixin.pre_save(self)
    method(self)
class ConcentratedEvil(type):
    tainted_classes = ['MyView'] # Add others as needed
    def __new__(mcs, name, bases, dict):
        if name in mcs.tainted_classes:
            print "tainting {0} with the power of evil".format(name)
            old_method = dict['pre_save']
            dict['pre_save'] = lambda x: do_evil(x, old_method)
            print dict.keys()
        return type.__new__(mcs, name, bases, dict)
class BaseView(object):
    pass
class MyMixin(object):
    __metaclass__ = ConcentratedEvil
    def pre_save(self):
        print "mixin presave"
class MyView(MyMixin, BaseView):
    def pre_save(self):
        print "view presave"

此时你可以:

>>> view = MyView()
>>> view.pre_save()
doing evil
mixin presave
view presave
>>>

我认为这只适用于如果MyMixin是在基类列表的前面

最新更新