object、type和class
- object 是 Python 的基础对象类,所有对象都是直接或间接的继承了 object(重用内容)
- type 是元类,定义了如何创建类,type(name, bases, dict) 可以动态创建类对象,Int、List、object 和 type 自身都是由 type 对象实例化(创建对象),同时 type(wh) 可以查看 wh 对象的类型,自定义的对象的类型都是 type
- class 是语法关键字(Python 少数不是对象的存在),class wh(hm) 可以静态定义一个继承 hm 对象的类对象 wh,实际上是调用的 type 可以简化编程
简化的说
- type 是自己的实例 isinstance(type, type) == True
- object 是 type 的实例 isinstance(object, type) == True
- type 是 object 的子类 issubclass(type, object) == True
- 但 object 不是 type 的子类 issubclass(object, type) == False。
以上构成了 Python 面向对象的基础
MRO与super
用户定义的对象通过 MRO 结构化表达,MRO 即 Method Resolution Order 是方法解析顺序将自己和所有继承的类做一个排序,自己优先级最高,排序使用C3算法,保证了三件事情
- MRO 里任意两个类的相对顺序和自己所有父类的 MRO 里这两个类的相对顺序一致。(单调性)
- MRO 里任意两个类的相对顺序和继承图里所有直接继承自这两个类的类在程序中声明的相对顺序一致。(局部优先)
- 如果两个类不具有直接的继承关系,那么找到两个类的最小公共子类,这个最小公共子类的多继承顺序靠前的分支上的类具有高优先级。
Python 的 super 是超类
super(type, class|object).method()
- super 本身是一个类对象而不是函数对象,如果 super 定义在类内方法中则参数可以省略不写(魔法函数隐操作)type 默认是当前所处类,决定了 MRO 中继承的起始,class|object 默认是 self 即当前所处类的实例,决定了 MRO
举例
class A:
def say(self):
print("A")
class B(A):
def say(self):
super().say()
class C(A):
def say(self):
print("C")
class M(B, C):
def say(self):
super().say()
m = M()
m.say()
# Output: C
显然执行 m.say() 时其 self 是 m ,其 MRO 等价于 M 的即 M,B,C,A,所以 super().say() 时将执行第二继承 B 中 super 虽然此 super 在类对象 B 但规则此时等价于执行 super(B, m).say() 最终执行了 C 的 say() 方法而不是 B 继承的 A 中的 say() 方法,因此在 Python 中写多继承时需要仔细检查包含隐操作的继承关系