在Python 2.7.10中
class OneMixin(object):
def __init__(self):
# super(OneMixin, self).__init__()
print "one mixin"
class TwoMixin(object):
def __init__(self):
# super(TwoMixin, self).__init__()
print "two mixin"
class Account(OneMixin, TwoMixin):
def __init__(self):
super(Account, self).__init__()
print "account"
Account.mro()是:[<class 'Account'>, <class 'OneMixin'>, <class 'TwoMixin'>, <type 'object'>]
虽然每个班级都列在MRO中,但是#34;两个混音&#34;没有打印。
如果我取消注释OneMixin和TwoMixin中的超级调用,则MRO完全相同,但是&#34;两个混合&#34; IS打印。
为何与众不同?我希望MRO中的所有东西都能被调用。
答案 0 :(得分:1)
这是因为super
用于将调用委托给类型的父类或兄弟类。 Python documentation对第二个用例进行了以下描述:
第二个用例是在动态执行环境中支持协作多重继承。此用例是Python独有的,在静态编译语言或仅支持单继承的语言中找不到。这使得实现“菱形图”成为可能,其中多个基类实现相同的方法。好的设计要求此方法在每种情况下都具有相同的调用签名(因为调用的顺序是在运行时确定的,因为该顺序适应类层次结构中的更改,并且因为该顺序可以包括在运行时之前未知的兄弟类)。
如果您从super
删除了OneMixin
来电,则无法将此次来电委托给MRO中的下一个类型。
答案 1 :(得分:1)
原因是您重写了父类的__init__
方法。无论您的__init__
方法是什么,方法解析顺序都是相同的。
super
的工作方式是将它传递给方法解析顺序中的下一个类。通过在OneMixin
中注释掉该行,您可以打破链条。 super
专为合作继承而设计。
此外,__init__
也不是真正的类构造函数。如果您将其视为其他语言的构造函数,这可能会让您失望。