未绑定的超级对象,超级(自我,自我)

时间:2019-09-24 09:06:59

标签: python-3.x debian super

我想问一下

sup = super(self, self)

David Beazley和Brian K. Jones撰写的Python Cookbook 3rd有很多这样的例子。这是本书中一个代码的简短摘录:

class MatchSignaturesMeta(type):
    def __init__(self, clsname, bases, clsdict):
        super().__init__(clsname, bases, clsdict)
        sup = super(self, self)  
        for name, value in clsdict.items():
        # ...
            prev_dfn = getattr(sup, name, None)
        # ...

class Root(metaclass=MatchSignaturesMeta):
    pass
class A(Root):
    def foo(self, x, y):
        pass
    # ...

通过实验,我知道第二个超级参数是强制性的。 sup打印为:

<super: <class 'Root'>, <Root object>>

在文档super中,他们说

“如果省略第二个参数,则返回的超级对象为 解除绑定。”

熟悉“绑定/未绑定方法”(将第一个参数绑定到类实例的函数)。 什么是“绑定对象”?

在示例中,正在创建Root类。我看不到显式的Root对象创建。我想问 根对象(来自上面的sup可打印表示形式)从哪里来?

在Debian GNU / Linux 9.11(拉伸)上使用Python 3.5.3

1 个答案:

答案 0 :(得分:0)

未绑定的超级对象是描述符-https://docs.python.org/3/glossary.html#term-descriptor。这意味着它作为对象属性进行访问时具有特殊的行为。

它内部没有方法定义。但是,它可以通过描述符的API创建绑定的超级对象。

考虑一下,我们有以下三个类和未绑定的超级对象:

class A(object):
    def method(self):
        return 'a'

class B(A):
    def method(self):
        return 'b'

sup = super(B)

如果尝试从中选择方法或属性,则会失败:

sup.method
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-2-de4aeea2d9e8> in <module>
      1 # If you try to get any method of A, it won't work
----> 2 sup.method

AttributeError: 'super' object has no attribute 'method'

但是,如果您尝试将其分配给其他属性,它将使用描述符的__get__方法,该方法可以这样工作:

def __get__(self, instance, owner=None):
    return super(self.__thisclass__, instance)

其中__thisclass__-是超级构造函数的单个参数(在我们的示例中为B)。

因此,如果我们尝试通过实例访问属性,我们将能够到达超类的方法:

class C(B):
    sup = super(B)

# same as super(B, self).method()
C().sup.method() # -> 'a'

但是请记住,您无法通过C.sup.method获得未绑定的超类方法。因为它等效于super(B, None),而后者又等效于super(B)