面试题答案
一键面试多重继承的概念
在Python中,多重继承指的是一个类可以从多个父类中继承属性和方法。例如:
class A:
def method_a(self):
return "Method from A"
class B:
def method_b(self):
return "Method from B"
class C(A, B):
pass
这里C
类同时继承了A
类和B
类的属性与方法。
潜在问题
- 命名冲突:如果多个父类中有相同名称的方法或属性,可能导致调用时的不确定性。例如,如果
A
类和B
类都有一个名为method
的方法,那么C
类实例调用method
时,不清楚会调用哪个父类的方法。 - 菱形问题:当一个类从多个父类继承,而这些父类又有共同的祖先类时,会出现菱形问题。这可能导致祖先类的方法或属性被重复继承和调用,造成不必要的开销和混乱。例如:
class D:
def method(self):
return "Method from D"
class E(D):
pass
class F(D):
pass
class G(E, F):
pass
这里G
类通过E
和F
间接继承了D
类两次,可能出现重复调用D
类方法的问题。
方法解析顺序(MRO)
方法解析顺序(MRO)是Python在多重继承情况下,确定调用哪个父类方法的顺序。Python使用C3线性化算法来计算MRO。
C3线性化算法
- 计算类的MRO列表:
- 类本身总是在其MRO列表的首位。
- 对于每个父类,计算其MRO列表。
- 使用合并操作来构建最终的MRO列表。合并过程如下:
- 从所有父类的MRO列表的第一个元素开始,如果该元素在其他列表中不在表头位置(除了它自己所在的列表),则将其添加到结果MRO列表中,并从所有列表中删除该元素。
- 重复上述步骤,直到所有列表都为空。
举例说明MRO解决冲突
class A:
def method(self):
return "Method from A"
class B(A):
def method(self):
return "Method from B"
class C(A):
def method(self):
return "Method from C"
class D(B, C):
pass
对于D
类,其MRO列表的计算如下:
D
类本身在首位,即[D]
。B
类的MRO是[B, A]
,C
类的MRO是[C, A]
。- 合并过程:
- 首先看
B
和C
,B
在B
类MRO表头,且不在C
类MRO表头,所以添加B
到结果,此时结果为[D, B]
,并从B
类MRO中删除B
,得到[A]
。 - 接着看
C
,C
在C
类MRO表头,且不在[A]
表头,所以添加C
到结果,此时结果为[D, B, C]
,并从C
类MRO中删除C
,得到[A]
。 - 最后看
A
,添加A
到结果,得到最终的MRO列表[D, B, C, A]
。 所以当D
类实例调用method
方法时,会优先调用B
类的method
方法,因为在MRO列表中B
类在前。
- 首先看