为什么没有调用所有的基类构造函数?

2024-09-19 23:32:29 发布

您现在位置:Python中文网/ 问答频道 /正文

在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中列出了每一个类,但并没有打印“two mixin”

如果我取消对OneMixin和TwoMixin中的超级调用的注释,那么MRO是完全相同的,但是会打印“TwoMixin”

为什么不同?我希望MRO里的每一件事都能被叫来


Tags: selfobjectinitdefaccountmixinoneclass
2条回答

这是因为super用于将调用委托给类型的父类或同级类Python documentation对第二个用例有如下描述:

The second use case is to support cooperative multiple inheritance in a dynamic execution environment. This use case is unique to Python and is not found in statically compiled languages or languages that only support single inheritance. This makes it possible to implement “diamond diagrams” where multiple base classes implement the same method. Good design dictates that this method have the same calling signature in every case (because the order of calls is determined at runtime, because that order adapts to changes in the class hierarchy, and because that order can include sibling classes that are unknown prior to runtime).

如果从OneMixin中删除super调用,那么在MRO中没有任何东西可以将调用委托给下一个类型

原因是您正在重写父类的__init__方法。不管__init__方法中有什么,方法的解析顺序都是相同的

super的工作方式是,它将按方法解析顺序将其传递给下一个类。通过注释掉OneMixin中的那一行,你就打破了链条super是为合作继承而设计的

而且,__init__也不是真正的类构造函数。如果你把它看作是其他语言中的构造器的话,这可能会把你绊倒

相关问题 更多 >