Python 继承使用super出错

Python 2.2以后使用super继承的父类属性的时候会报错,这篇文章通过讲解新式类和旧类的区别来解决super报错的问题。

Python 2.2以后使用super继承的父类属性的时候会报错,这篇文章通过讲解新式类和旧类的区别来解决super报错的问题。

在Python的类中去继承父类的属性, 一般的写法为:

class Father:
    def __init__(self):
        print "I'm Father"

class Child(Father):
    def __init__(self):
        Father.__init__(self)
        print "I'm Child"
>>>f = Child()
I'm Father
I'm Child

如果在多重继承的问题中,例如菱形继承(钻石问题),则需要用到super来解决。但是super只能用在继承基类”object”的新式类中,不能用于以前的经典类,否则报错:

class Father:
    def __init__(self):
        print "I'm Father"

class Child(Father):
    def __init__(self):
        super(Child, self).__init__() 
        print "I'm Child"
>>>f = Child()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __init__
TypeError: must be type, not classobj

原因如下:

解决的方法是设置Father继承Object

class Father(object):
    def __init__(self):
        print "I'm Father"

class Child(Father):
    def __init__(self):
        super(Child, self).__init__() 
        print "I'm Child"
>>>f = Child()
I'm Father
I'm Child

以下关于《旧类和新式类》的内容摘自:http://blog.csdn.net/jb19900111/article/details/20228341

  • python的新式类是2.2版本引进来的,我们可以将之前的类叫做经典类或者旧类。
  • 为什么要在2.2中引进new style class呢?官方给的解释是:为了统一类(class)和类型(type)。
  • 在2.2之前,比如2.1版本中,类和类型是不同的,如a是ClassA的一个实例,那么a.__class__返回 ‘ class __main__.ClassA‘ ,type(a)返回总是<type ‘instance’>。而引入新类后,比如ClassB是个新类,b是ClassB的实例,b.__class__和type(b)都是返回‘class ‘__main__.ClassB’ ,这样就统一了。
  • 引入新类后,还有其他的好处,比如更多的内置属性将会引入,描述符的引入,属性可以来计算等等。
  • 为了向前兼容,默认情况下用户定义的类为经典类,新类需要继承自所有类的基类 object 或者继承自object的新类。
  • 值得注意的地方是,虽然使用的是最新的python(2.7),但是一些特性不会在旧式类起作用。
  • 所以,为了确保自己使用的是新式类,有以下方法:
    • 把这个赋值语句放在类模块代码的最前面 __metaclass__ = type(前面有提过)。
    • 自己的类都从内建类object直接或者间接地继承。
    • 如果不需要兼容旧式类,旧版本的类,那么就保持都是新式类。
    • 当然,在Python3里面,不存在这些问题了,因为所有的类都是object类的子类(隐式)。