为什么python中的继承要求父类显式继承对象?

时间:2014-12-26 09:34:07

标签: python inheritance

以下是我的代码的两个版本:

非工作

class A:
    def __init__(self):
        print "I am A "

class B:
    def __init__(self):
        print "I am B "

class C(A, B):
    def __init__(self):
        super(C, self).__init__()

c = C()

这引发了例外:

    super(C, self).__init__()  
TypeError: must be type, not classobj  

工作版

class A(object):
    def __init__(self):
         print "I am A "

class B:
    def __init__(self):
         print "I am B "

class C(A, B):
    def __init__(self):
         super(C, self).__init__()

c = C()

如果其中一个父类明确地继承了 object ,则没有异常,并且事情可以按预期工作。任何解释,为什么?

使用上面的工作,它打印“我是A”而不是“我是B”,这意味着它只初始化A类,而不是B类。初始化子级中的多个父类类?

2 个答案:

答案 0 :(得分:5)

那是因为super仅适用于新式类(继承自object)。在Python 2中,object在继承层次结构中没有的类(如第一个示例)称为旧式类,不应在任何地方使用。

这是一个古老的历史文物,从Python第一次添加OO开始,开发人员就错了。除此之外,新式类允许使用super,描述符协议(属性),并对多重继承的处理方式进行了一些修复。 super是其中之一,但最重要的是为钻石继承案例计算方法解析顺序的方式(A继承自B和C,它们都从D继承)。在此处阅读更多相关信息:http://python-history.blogspot.fr/2010/06/method-resolution-order.html

请注意,Python 3完全抛弃了旧式类,因此在Python 3中,所有类都是新式类,并且继承自对象,无论它们是否明确地执行。

答案 1 :(得分:2)

super()仅适用于新式类(任何继承自object的类)。因此,您无法将类对象传递给super

  

super有两个典型的用例。在具有单继承的类层次结构中,super可用于引用父类而不显式命名它们,从而使代码更易于维护。这种用法与其他编程语言中super的使用密切相关。

第二个用例是在动态执行环境中支持协作多重继承。此用例是Python独有的,在静态编译语言或仅支持单继承的语言中找不到。这使得实现“菱形图”成为可能,其中多个基类实现相同的方法。好的设计要求此方法在每种情况下都具有相同的调用签名(因为调用的顺序是在运行时确定的,因为该顺序适应类层次结构中的更改,并且因为该顺序可以包括在运行时之前未知的兄弟类)。

典型的超类调用如下所示:

class C(B):
    def method(self, arg):
        super(C, self).method(arg)