Python - 揭秘使用 super() 调用祖父母方法

Python - Demystifying the use of super() to call grandparent method

我似乎无法完全理解 super() 在调用 grandparent class 方法时的真正工作原理。例如假设我们有以下代码

class A():
    def __init__(self):
        print("initializing A")
    def method(self):
        print("method A")

class B(A):
    def __init__(self):
        print("initializing B")
    def method(self):
        print("method B")

class C(B):
    def __init__(self):
        print("initializing C")
    def method(self):
        super(B, self).method()

c = C()
c.method()

这将输出

initializing C
method A

我不明白为什么语法(意思是 super(Parent, self).method())是这样的,更重要的是幕后发生了什么。 Python 官方文档 (here) 说

class super([type[, object-or-type]]) - Return a proxy object that delegates method calls to a parent or sibling class of type. This is useful for accessing inherited methods that have been overridden in a class. The object-or-type determines the method resolution order to be searched. The search starts from the class right after the type.

为什么传递给 super([type[, object-or-type]])type 必须是 parent class B 而不是 grandparent classA?传递 self(在本例中是 class C 的实例)如何帮助确定要搜索的方法解析顺序?

C的解析顺序为[C, B, A, object]。当您使用 super 时,您正在寻找提供请求方法的 next class。在 C.methodsuper()super(C, self) 中是等价的:在 class after[=33= 中查找 method 的第一个定义] C。当您将 B 作为第一个参数传递时,您是在 B 之后的 class 中请求 method 的第一个定义。

(第二个参数,如果不是 self,将用于 select 一个完全不同的 MRO,而不仅仅是在适当的 MRO 中用于搜索的不同起始位置。)

super 的其他参数的用例非常罕见,因此值得向语言本身添加特殊逻辑以允许 super() 用于显式参数。 (它们不仅仅是默认函数参数,因为“默认”值取决于调用 super 的上下文。)