class
MRO 方法搜索顺序 .mro
MRO是method resolution order,主要用于在对继承是判断方法、属性的调用路径【顺序】,其实也就是继承父类方法时的顺序表。Python中针对类提供了一个内置属性__mro__可以查看方法的搜索顺序。
class A:
pass
class B:
pass
class C(A,B):
pass
# (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
print(C.__mro__)
super()
super 所代表的并不是简单的父类。完整的super()签名是:super(type, object_or_type=None),表示代理的是 MRO 序列中 type 的下一个类,它可能是 type 的父类,也可能是 type 的兄弟。无论是否有实际作用,在所有类的初始化方法中,都加上 super().init() 是一个好的习惯。
class A:
def __init__(self):
print("A enter")
super().__init__()
print("A exit")
def add(self):
print('A add enter')
super().add()
print('A add exit')
class B(A):
def __init__(self):
print("B enter")
super().__init__()
print("B exit")
def add(self):
print('B add enter')
super().add()
print('B add exit')
class C:
def __init__(self):
print("C enter")
super().__init__()
print("C exit")
def add(self):
print('C add enter')
super().add()
print('C add exit')
class E(A):
def __init__(self):
print("E enter")
super().__init__()
print("E exit")
def add(self):
print('E add enter')
super().add()
print('E add exit')
class D(B, C):
def __init__(self):
print("D enter")
super().__init__()
print("D exit")
def add(self):
print('D add enter')
super().add()
print('D add exit')
print(D.__mro__)
d = D()
d.add()
//对于__init__(),调用顺序根据MRO为:D->B->A->C->object->object->C->A->B->D,因为object也有__init__()函数,所以能正常运行。
//对于add(),调用顺序根据MRO为:D->B->A->C->object->object->C->A->B->D,因为object没有add()函数,所以当执行到object.add()时,程序报错。
//output
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.A'>, <class '__main__.C'>, <class 'object'>)
D enter
B enter
A enter
C enter
C exit
A exit
B exit
D exit
D add enter
B add enter
A add enter
C add enter
Traceback (most recent call last):
File "c:\Users\CNMIZHU7\Source\repos\UtilityTools\PMTWUserScript\PythonTest.py", line 100, in <module>
d.add()
File "c:\Users\CNMIZHU7\Source\repos\UtilityTools\PMTWUserScript\PythonTest.py", line 95, in add
super().add()
File "c:\Users\CNMIZHU7\Source\repos\UtilityTools\PMTWUserScript\PythonTest.py", line 61, in add
super().add()
File "c:\Users\CNMIZHU7\Source\repos\UtilityTools\PMTWUserScript\PythonTest.py", line 50, in add
super().add()
File "c:\Users\CNMIZHU7\Source\repos\UtilityTools\PMTWUserScript\PythonTest.py", line 73, in add
super().add()
^^^^^^^^^^^
AttributeError: 'super' object has no attribute 'add'
类属性和实例属性
python 的属性分为实例属性和类属性,实例属性是以self为前缀的属性,如果构造函数中定义的属性没有使用self作为前缀声明,则该变量只是普通的局部变量,类中其它方法定义的变量也只是局部变量,而非类的实例属性。