python面向对象名称查找顺序
名字的查找顺序
不继承的情况
对象中没有要查找的名称,会去类中查找。
class A:
cls_A = 'from A'
a = A()
print(a.__dict__) # 空的
print(a.cls_A) # from A
对象中有要查找的名称,则输出在对象中的名称。
class A:
cls_A = 'from A'
a = A()
a.__dict__['cls_A'] = 'from a'
print(a.__dict__) # {'cls_A': 'from a'}
print(a.cls_A) # from a
总结:先从对象自己的名称空间中查找,没有则去类里面的名称空间查找
单继承的情况
# 父类A
class A:
def f1(self):
print('from A.f1')
def f2(self):
print('from A.f2')
self.f1()
# 子类MyClass
class MyClass(A):
def f1(self):
print('from MyClass.f1')
obj = MyClass()
obj.f2()
"""
执行结果:
from A.f2
from MyClass.f1
"""
总结:先从对象自己的名称空间中查找,没有则取去类中查找,如果还没有并且类有父类则去父类中查找,以此往复下去。
多继承的情况(了解)
在python2中存在经典类与新式类。
在python3中只有新式类。
区分的关键在于是否继承了一个默认的object类
-
新式类:直接或者间接继承了object或者其子类的类
-
经典类:不继承任何的类
非菱形继承的情况下:
父类中名字的查找顺序就是按照继承时从左往右依次查找,如果多个父类还有分类,那么遵循"深度优先"。如下图的查找顺序为:A->B->E->C->D->F
菱形继承的情况下:
父类中名字的查找顺序就是按照继承时从左往右依次查找,如果多个父类还有分类,那么遵循"广度优先"。如下图的查找顺序为:A->B->E->C->D->F->G
总结:父类中名字的查找顺序就是按照继承时从左往右依次查找,如果查找的父类还有个父类,优先查找;如果所有的父类有着共同的父类,那么这个父类会最后查找。