我在Django中有以下代码:
class Parent(models.Model):
def save(self):
# Do Stuff A
class Mixin(object):
def save(self):
# Do Stuff B
class A(Parent, Mixin):
def save(self):
super(A, self).save()
# Do stuff C
现在,我想使用mixin而不会在Parent中剔除保存行为。因此,当我保存时,我想要做C,B和A的东西。我已经读过Calling the setter of a super class in a mixin但是我没有得到它并且阅读了超级文档它似乎没有回答我的问题。
问题是,我应该在mixin中添加什么来确保它能够完成B并且不会阻止Stuff A发生?
答案 0 :(得分:8)
如何在mixin课程中调用super?
class Parent(object):
def test(self):
print("parent")
class MyMixin(object):
def test(self):
super(MyMixin, self).test()
print("mixin")
class MyClass(MyMixin, Parent):
def test(self):
super(MyClass, self).test()
print("self")
if __name__ == "__main__":
my_obj = MyClass()
my_obj.test()
这将输出为:
$ python test.py
parent
mixin
self
答案 1 :(得分:5)
从超类调用实现的最佳做法是使用super()
:
class Mixin(object):
def save(self):
super(Mixin, self).save()
# Do Stuff B here or before super call, as you wish
重要的是你在每个类中调用super()
(以便它一直传播)但不是最顶层的(基类)类,因为它的超类没有save()
。
请注意,当您调用super(Mixin, self).save()
时,您实际上并不知道超级类在执行后会是什么。这将在稍后定义。
与其他语言不同,在python中,结束类将始终具有从中继承的类的线性列表。这被称为MRO(Method Resolution Order)。从MRO Python决定在super()
调用上做什么。您可以通过这种方式查看MRO对您的课程的影响:
>>> A.__mro__
(<class '__main__.A'>, <class '__main__.Parent'>, <class '__main__.Model'>, <class '__main__.Mixin'>, <type 'object'>)
所以,A
的超级是Parent
,Parent
的超级是Model
,Model
的超级是Mixin
, Mixin
的超级是object
。
这是错误的,所以你应该将A
的父母改为:
class A(Mixin, Parent):
然后你会有一个更好的MRO:
>>> A.__mro__
(<class '__main__.A'>, <class '__main__.Mixin'>, <class '__main__.Parent'>, <class '__main__.Model'>, <type 'object'>)
答案 2 :(得分:1)
@Click2Death 答案是正确的,但是,当您在 mixin 类中调用 super().test()
时,大多数 IDE 会声称 test
未解析,这是正确的。
这里是如何让您的 IDE 满意并让您的代码更好。
class Parent(object):
def test(self):
print("parent")
class MyMixin(object):
def test(self):
super_test = getattr(super(), 'test')
if super_test and callable(super_test):
super_test()
print("mixin")
class MyClass(MyMixin, Parent):
def test(self):
super().test()
print("self")
if __name__ == "__main__":
my_obj = MyClass()
my_obj.test()
这是 Python 3 代码,要使其与 Python 2 一起使用,您需要将两个参数传递给 super(MyClass, self)
调用
答案 3 :(得分:0)
为了在 Django 上下文中扩展 Vladimir Prudnikov's answer,模板视图 mixin 类的结构可以如下所示。
Microsoft.CSharp