我想问一下
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
答案 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)
。