在 python 多重继承中,一个父级是否可以在不知道另一个父级是什么的情况下访问另一个父级?
In python multiple inheritance, is it possible for one parent to access another parent without knowing what that parent is?
在我的代码中,我有继承关系 B -> C -> D
,并且这里有一个特别感兴趣的函数 f
class C(B):
def f(self):
if <some condition>:
B.f(self)
else:
<do other stuff>
问题是B
在现实中有多种可能,但C
的逻辑是一样的。一个直接的方法是多次使用线性继承,即
B1 -> C1 -> D1
B2 -> C2 -> D2
B3 -> C3 -> D3
但是,这很浪费。然后我在考虑使用多重继承
D1(C, B1)
D2(C, B2)
D3(C, B3)
那么问题是 C.f()
如何访问 B1.f()
(B2
、B3
也一样)因为它只知道 B1
的存在D1
?
在这种情况下使用多重继承是个坏主意吗?还是有比具有多个 C
的直接线性继承和多重继承(如果可行)更好的方法?
这是多重继承的一个经典问题,最终导致一些语言完全退出多重继承。
然而,Python 只是通过巧妙设计的 "method resolution order" (mro) 算法逃脱了,后来,随着 super
内置调用的出现。 https://www.python.org/download/releases/2.3/mro/
中详细介绍了该算法及其历史
但是,历史长短,它确实如预期的那样工作"by heart"。例如,将此代码粘贴到交互式解释器上:
class A: pass
class B(A):
def f(self): raise NotImplementedError
class C(B):
def f(self):
super().f()
print("C")
class B1(B): f = lambda s: print("B1")
class B2(B): f = lambda s: print("B2")
class D(C, B1): pass
class D1(C, B2): pass
我们在修补时得到了这些结果:
In [25]: D().f()
B1
C
In [26]: D1().f()
B2
C
In [27]: D.__mro__
Out[27]: (__main__.D, __main__.C, __main__.B1, __main__.B, __main__.A, object)
在我的代码中,我有继承关系 B -> C -> D
,并且这里有一个特别感兴趣的函数 f
class C(B):
def f(self):
if <some condition>:
B.f(self)
else:
<do other stuff>
问题是B
在现实中有多种可能,但C
的逻辑是一样的。一个直接的方法是多次使用线性继承,即
B1 -> C1 -> D1
B2 -> C2 -> D2
B3 -> C3 -> D3
但是,这很浪费。然后我在考虑使用多重继承
D1(C, B1)
D2(C, B2)
D3(C, B3)
那么问题是 C.f()
如何访问 B1.f()
(B2
、B3
也一样)因为它只知道 B1
的存在D1
?
在这种情况下使用多重继承是个坏主意吗?还是有比具有多个 C
的直接线性继承和多重继承(如果可行)更好的方法?
这是多重继承的一个经典问题,最终导致一些语言完全退出多重继承。
然而,Python 只是通过巧妙设计的 "method resolution order" (mro) 算法逃脱了,后来,随着 super
内置调用的出现。 https://www.python.org/download/releases/2.3/mro/
但是,历史长短,它确实如预期的那样工作"by heart"。例如,将此代码粘贴到交互式解释器上:
class A: pass
class B(A):
def f(self): raise NotImplementedError
class C(B):
def f(self):
super().f()
print("C")
class B1(B): f = lambda s: print("B1")
class B2(B): f = lambda s: print("B2")
class D(C, B1): pass
class D1(C, B2): pass
我们在修补时得到了这些结果:
In [25]: D().f()
B1
C
In [26]: D1().f()
B2
C
In [27]: D.__mro__
Out[27]: (__main__.D, __main__.C, __main__.B1, __main__.B, __main__.A, object)