为什么在 `super(A, self)` 中对象出现在 `self` 之前?

Why in `super(A, self)` does the object come before the `self`?

我想知道为什么调用超级 classes 的构造函数的语法将 Child 对象作为参数传递给 self,以及这些参数的作用是什么以继承父方法的目标 class.

class Child(SomeBaseClass):
    def __init__(self):
        super(Child, self).__init__()

我已阅读以下帖子,但在其中我找到了原因:

  1. The 'super' docs

  2. What does 'super' do in Python?

  3. this post 中我找到了这句话:

    super(class, subclass).method returned a bound method, not an unbound one

    但我仍然无法理解这种语法的含义。

欣赏此语法的详细说明。

super 参数的顺序反映了 Python 的未绑定和绑定 methods/descriptors 的想法。简而言之,第二个参数是 optional,因此必须在所需的第一个参数之后。

Built-in Functions: super([type[, object-or-type]])

[...]

If the second argument is omitted, the super object returned is unbound. If the second argument is an object, isinstance(obj, type) must be true. If the second argument is a type, issubclass(type2, type) must be true (this is useful for classmethods).

这反映了方法调用 self.method() 等同于 Class.method(self),即操作数的顺序是 Class 然后 self.*


Python methods/descriptors 有两种形式:unbound 定义 class 和 bound 在他们的实例上。*

>>> class Base:
...     def method(self): print('called Base method')
...
>>> Base.method     # unbound method
<function __main__.Base.method(self)>
>>> Base().method   # bound method
<bound method Base.method of <__main__.Base object at 0x10dd0e910>>
>>> Base().method()
called Base method

绑定描述符是通过采用未绑定描述符并将其绑定到实例来创建的。这是在描述符协议中编码和实现的。

>>> instance = Base()
>>> unbound = Base.method
>>> unbound.__get__(instance)
<bound method Base.method of <__main__.Base object at 0x10dd14510>>
>>> unbound.__get__(instance)()
called Base method

super 类型默认未绑定。通过描述符协议或传递实例来绑定它是等效的。

>>> class Child(Base): ...
>>> instance = Child()
>>> super(Child, instance)
<super: __main__.Child, <__main__.Child at 0x10dcda9d0>>
>>> super(Child).__get__(instance)
<super: __main__.Child, <__main__.Child at 0x10dcda9d0>>

在任何一种情况下,class 必须在实例 之前先传递。


From the python-dev archive:

Add 'super', another new object type with magical properties.

super(type) -> unbound super object

super(type, obj) -> bound super object; requires isinstance(obj, type)

Typical use to call a cooperative superclass method:

class C(B):
    def meth(self, arg):
        super(C, self).meth(arg);

* 此描述掩盖了描述符协议的更详细信息。例如,method/descriptor 也可以绑定到 class。