了解 Python 中的嵌套继承
Understanding Nested Inheritance in Python
这是我的主要代码的简化代码,说明了我获得的行为。
假设我有一个 main class (MAIN) 和两个从它继承的 classes (A,B)。这个mainclass有个方法被A覆盖了,B没有覆盖,也就是说B继承了main的方法
然后我有一个 class D 继承自 A 和 B,并且有一个调用上述方法的方法。根据我对多重继承工作方式的理解,如果我将 D 定义为 class D(A,B)
,那么如果 A 和 B 具有共享方法,则调用 D.method() 将调用 A.method,反之亦然-versa(即如果 class D(B,A)
则调用 B.method。以下代码举例说明了此文本。
class MAIN(object):
def __init__(self):
pass
def print(self):
print('HELLO MAIN')
class A(MAIN):
def __init__(self):
pass
def print(self):
print('HELLO A')
class B(MAIN):
def __init__(self):
pass
class C(A,B):
def __init__(self):
pass
def Cprint(self):
self.print()
c = C()
c.Cprint()
class C(B,A):
def __init__(self):
pass
def Cprint(self):
self.print()
c = C()
c.Cprint()
但是此代码始终打印 'HELLO A',即即使在 class C(B,A)
的情况下,我也没有像我期望的那样得到 HELLO MAIN。这里发生了什么?非常感谢
mro
是 (C, A, B, MAIN)
与 class C(A, B)
和 (C, B, A, MAIN)
与 class C(B, A)
。在这两种情况下,A
都在 MAIN
之前。 B
没有定义 .print
,所以没关系。
uplooks方法是这样的:(伪代码)
def find_attribute(obj, name):
if name in obj.__dict__:
return obj.__dict__[name]
mro = type(obj).__mro__
for cls in mro:
if name in cls.__dict__:
return cls.__dict__[name] # (Here a bit more magic for descriptors happens)
raise AttributeError(name)
对于 类 他们的 __dict__
是这样的:
MAIN.__dict__ = {"print": <method MAIN.print>}
A.__dict__ = {"print": <method A.print>}
B.__dict__ = {}
C.__dict__ = {"Cprint": <method C.Cprint>}
如您所见,B
没有定义 print
,因此在 mro=(C, B, A, MAIN)
中找到的第一个 print
在 A
.
您到处都在继承 Class A 并且 class A 覆盖了主要函数 print() 这就是为什么您没有得到“HELLO MAIN”
class C(B):
def __init__(self):
pass
def Cprint(self):
self.print()
仅继承 B class,它不会覆盖 Main class 打印功能,然后您将获得 HELLO MAIN 输出
这是我的主要代码的简化代码,说明了我获得的行为。
假设我有一个 main class (MAIN) 和两个从它继承的 classes (A,B)。这个mainclass有个方法被A覆盖了,B没有覆盖,也就是说B继承了main的方法
然后我有一个 class D 继承自 A 和 B,并且有一个调用上述方法的方法。根据我对多重继承工作方式的理解,如果我将 D 定义为 class D(A,B)
,那么如果 A 和 B 具有共享方法,则调用 D.method() 将调用 A.method,反之亦然-versa(即如果 class D(B,A)
则调用 B.method。以下代码举例说明了此文本。
class MAIN(object):
def __init__(self):
pass
def print(self):
print('HELLO MAIN')
class A(MAIN):
def __init__(self):
pass
def print(self):
print('HELLO A')
class B(MAIN):
def __init__(self):
pass
class C(A,B):
def __init__(self):
pass
def Cprint(self):
self.print()
c = C()
c.Cprint()
class C(B,A):
def __init__(self):
pass
def Cprint(self):
self.print()
c = C()
c.Cprint()
但是此代码始终打印 'HELLO A',即即使在 class C(B,A)
的情况下,我也没有像我期望的那样得到 HELLO MAIN。这里发生了什么?非常感谢
mro
是 (C, A, B, MAIN)
与 class C(A, B)
和 (C, B, A, MAIN)
与 class C(B, A)
。在这两种情况下,A
都在 MAIN
之前。 B
没有定义 .print
,所以没关系。
uplooks方法是这样的:(伪代码)
def find_attribute(obj, name):
if name in obj.__dict__:
return obj.__dict__[name]
mro = type(obj).__mro__
for cls in mro:
if name in cls.__dict__:
return cls.__dict__[name] # (Here a bit more magic for descriptors happens)
raise AttributeError(name)
对于 类 他们的 __dict__
是这样的:
MAIN.__dict__ = {"print": <method MAIN.print>}
A.__dict__ = {"print": <method A.print>}
B.__dict__ = {}
C.__dict__ = {"Cprint": <method C.Cprint>}
如您所见,B
没有定义 print
,因此在 mro=(C, B, A, MAIN)
中找到的第一个 print
在 A
.
您到处都在继承 Class A 并且 class A 覆盖了主要函数 print() 这就是为什么您没有得到“HELLO MAIN”
class C(B):
def __init__(self):
pass
def Cprint(self):
self.print()
仅继承 B class,它不会覆盖 Main class 打印功能,然后您将获得 HELLO MAIN 输出