一、什么是经典类,什么新式类?
经典类、新式类是站在类否继承 object 类的前提下的一个命名, 一个概念。
1.1 定义:
经典类: 当前类没有继承 object 类,那么当前类就是 经典类。
新式类:当前类继承 object 类,那么当前类就是 新式类。
1.2 在ptyhon的不同版本中,经典类与新式类的存在情况不一样
1.2.1 在 python3.X 版本中,由于所有的类 默认都继承 object类,所以有的类 都是 新式类。
结论:在python3.x版本中,只有新式类。
解释器为python3.6 环境
class Person1:pass # 默认继承 object 类 class Person2(object):pass print(Person1.__bases__) # (<class 'object'>,) print(Person2.__bases__) # (<class 'object'>,) print(Person1.__dict__) # 返回一个字典,字典中存放了 类的所有属性和值
1.2.2 在python2.7 版本中,所有的类 ,默认都不继承 object 类,所以默认情况下,类就是经典类,如果显示声明一个类 继承 object 类,或者 一个类 通过 继承关系的传递 继承了object类,那么就成为新式类。
结论:在python 2.7 版本中,经典类和新式类 并存。
# 以下是在python2.7环境中执行的命令结果: class Person3: pass # 默认不继承(不主动) object 类 print(Person3.__bases__) # () class Person4(object):pass # 显示声明一个类 继承 object 类 print(Person4.__bases__) # (<type 'object'>,) class Base: def func(self): print("我是Base类") class child: def func(selfself): print("我是child类") print(issubclass(child,object)) # False 在python2.7 中,在默认情况下 ,都不继承 object类,是经典类 print(issubclass(Base,object)) # False class Base(object): # 显示声明一个类 继承 object 类 def func(self): print("我是Base类") class child(Base): def func(selfself): print("我是child类") print(issubclass(child,object)) # True 可见继承具有传递性 print(issubclass(Base,object)) # True
1.3 当类是 经典类 或者 新式类 时,在多继承环境下,从父类中寻找 成员的顺序问题,或者叫找寻父类成员的方式:
1.3.1 当类是 经典类 时,在多继承环境下,会按照 “深度优先方式” 查找:
# 经典类,在多继承环境,在父类中寻找成员的方式,遵循 “深度优先” 原则 class G: # def find(self): # print("G") pass class A: # def find(self): # print("A") pass class B(A): # def find(self): # print("B") pass class C(A): # def find(self): # print("C") pass class D(B,G): # def find(self): # print("D") pass class E(C): # def find(self): # print("E") pass class F(D,E): # def find(self): # print("F") pass f_obj = F() f_obj.find() # F --> D --> B --> A --> G --> E --> C -->
总结:“深度优先”查找方式,从当前类开始查找 成员属性或方法 ,当前类没有,则查找 第一个继承的父类 ,若没有,则查找父类的父类,沿着父类的父类....,一直查找下去,查找到到就执行,若一直查找到了最顶层的类,则沿原路返回,看有没有未查找的节点,左树枝查找完毕没有,则回到 当前类 这个根节点,查找第二个直接继承的节点,的右树枝。依次类推。
1.3.2 当前类 是 新式类 时, 在多继承环境下,查找父类的成员时,会遵循 “广度优先”方式 查找:
结论: 当 尝试 从B的父类 A 查找成员时,由于A 有两条路径,可以达到,直接回到 F 类,开始另一个分支的查找
==
==
---
----
==
====
1.4 经典类和新式类的特点:
1.4.1 新式类:
所有的多继承关系寻找 方法的顺序 --- 遵循广度优先算法
继承object
mro方法
super(); super 不是单纯的找父类,而是遵循mro顺序
1.4.2 经典类
不主动继承object
经典类在找父类方法的过程中,遵循 深度优先
不提供mro方法 和 super