在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是在基类列表的前面