在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,并打印"查看presave"只要。是否还有另一种狡猾的方式我可以写MyMixin
以强制所有客户端视图都不记得拨打super()
?
答案 0 :(得分:1)
这个答案是概念证明,而不是推荐。 请勿在生产代码中执行此操作。您将创建维护噩梦。我同意那些评论你的问题,即唯一安全的方法是编辑派生类。
尽管如此,技术上可以使用metaclass。
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位于基类列表的前面时才有效。