Python 2.2以后使用super继承的父类属性的时候会报错,这篇文章通过讲解新式类和旧类的区别来解决super报错的问题。
在Python的类中去继承父类的属性, 一般的写法为:
[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
[/python]
如果在多重继承的问题中,例如菱形继承(钻石问题),则需要用到super来解决。但是super只能用在继承基类”object”的新式类中,不能用于以前的经典类,否则报错:
[python]
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
[/python]
原因如下:
解决的方法是设置Father继承Object
[python]
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
[/python]
以下关于《旧类和新式类》的内容摘自: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类的子类(隐式)。
发表回复