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类的子类(隐式)。