1.新式类与经典类html
在Python 2及之前的版本中,由任意内置类型派生出的类(只要一个内置类型位于类树的某个位置),都属于“新式类”,都会得到全部“新式类”的特性;反之,即不禁任意内置类型派生出的类,则称之为“经典类”。python
“新式类”和“经典类”的区分在Python 3以后就已经不存在,在Python 3.x以后的版本,由于全部的类都派生自内置类型object(即便没有显示的继承object类型),即全部的类都是“新式类”。算法
官方文档 https://www.python.org/doc/newstyle/函数
2.继承顺序的区别spa
主要是在多重继承时才会遇到这个问题。code
经典类的钻石继承是深度优先,即从下往上搜索;新式类的继承顺序是采用C3算法(非广度优先)。htm
对经典类进行代码验证(全部经典类的代码必须在Python2下运行,下同),ClassicClassB 继承自 ClassicClassA,SubClassicClass继承自ClassicClassB,ClassicClassC:blog
class ClassicClassA(): var = 'Classic Class A' class ClassicClassB(ClassicClassA): pass class ClassicClassC(): var = 'Classic Class C' class SubClassicClass(ClassicClassB, ClassicClassC): pass if __name__ == '__main__': print(SubClassicClass.var)
在SubClassicClass对var属性进行搜索的过程当中,根据从下到上的原则,会优先搜索ClassicClassB,而ClassicClassB没有var属性,会继续往上搜索ClassicClassB的超类ClassicClassA,在ClassicClassA中发现var属性后中止搜索,var的值为ClassicClassA中var的值;而ClassicClassC的var属性从始至终都未被搜索到。继承
从运行结果能够看出,输出的是Classic Class A,可见类继承的搜索是深度优先,由下至上进行搜索。文档
Classic Class A
新式类的继承顺序并不是是广度优先,而是C3算法,只是在部分状况下,C3算法的结果恰巧与广度优先的结果相同。
对新式类的继承搜索顺序进行代码验证,新式类中,可使用mro函数来查看类的搜索顺序(这也算是一个区别),如SubNewStyleClass.mro()。
class NewStyleClassA(object): var = 'New Style Class A' class NewStyleClassB(NewStyleClassA): pass class NewStyleClassC(NewStyleClassA): var = 'New Style Class C' class SubNewStyleClass(NewStyleClassB, NewStyleClassC): pass if __name__ == '__main__': print(SubNewStyleClass.mro()) print(SubNewStyleClass.var)
从代码运行结果看,恰巧与从左至右的广度优先预期结果相同。
[<class '__main__.SubNewStyleClass'>, <class '__main__.NewStyleClassB'>, <class '__main__.NewStyleClassC'>, <class '__main__.NewStyleClassA'>, <type 'object'>] New Style Class C
可是不表明新式类的继承顺序就是广度优先,能够稍微修改下代码进行验证:NewStyleClassC改成继承自object
class NewStyleClassA(object): var = 'New Style Class A' class NewStyleClassB(NewStyleClassA): pass class NewStyleClassC(object): var = 'New Style Class C' class SubNewStyleClass(NewStyleClassB, NewStyleClassC): pass if __name__ == '__main__': print(SubNewStyleClass.mro()) print(SubNewStyleClass.var)
运行结果再也不符合广度优先:
[<class '__main__.SubNewStyleClass'>, <class '__main__.NewStyleClassB'>, <class '__main__.NewStyleClassA'>, <class '__main__.NewStyleClassC'>, <type 'object'>] New Style Class A
可见,新式类的继承顺序并不是广度优先,而是C3算法。至于C3算法,之后再另外详细写。
3.类实例类型的区别
在经典类中,全部的类都是classobj类型,而类的实例都是instance类型。类与实例只有经过__class__属性进行关联。这样在判断实例类型时,就会形成不便:全部的实例都是instance类型。
class A():pass class B():pass a = A() b = B() if __name__ == '__main__': print(type(a)) print(type(b)) print(type(a) == type(b))
type(a) == type(b)的结果永远为True,那这样的比较就毫无心义。
更为麻烦的是,经典类的实例是instance类型,而内置类的实例却不是,没法统一。
经过代码判断下内置类型list的实例[1, 2, 3]是什么类型
print(type([1, 2, 3]))
运行结果,是list类型
<type 'list'>
内置类的实例类型和经典类的实例类型彻底不一样,容易形成困惑,不利于代码的统一。
这个问题在Python 3以后就不复存在了,由于Python3中全部的类都是新式类,新式类中类与类型已经统一:类实例的类型是这个实例所建立自的类(一般是和类实例的__class__相同),而再也不是Python 2.x版本中的“instance”实例类型。
更详细的:http://www.cnblogs.com/blackmatrix/p/5594109.html
大概就想到这几点,其余的有想到再补充。