在Python website上找到的关于super()
的文档说它返回一个代理对象,该对象将方法调用委托给父类或兄弟类。在super considered super,how does super() work with multiple inheritance 和super considered harmful上找到的信息解释说,实际上使用了mro
中的下一种方法。我的问题是,如果使用super(object, self).some_method()
会发生什么?由于object
通常出现在mro
列表的末尾,我猜搜索将立即到达末尾,但会出现一个异常。但实际上,代理本身的方法似乎是被调用的,如显示超级对象本身的super(object, self).__repr__()
所示。我想知道使用object
的super()
的行为是不是根本不委托方法。如果是这样的话,我想知道是否有可靠的材料提到过它,以及它是否适用于其他Python实现。
class X(object):
def __init__(self):
# This shows [X, object].
print X.mro()
# This shows a bunch of attributes that a super object can have.
print dir(super(object, self))
# This shows something similar to <super object at xxx>
print(object, self)
# This failed with `super() takes at least one argument`
try:
super(object, self).__init__()
except:
pass
# This shows something like <super <class 'object'>, <'X' object>>.
print(super(object, self).__repr__())
# This shows the repr() of object, like <'X' object at xxx>
print(super(X, self).__repr__())
if __name__ == '__main__':
X()
发布于 2018-06-02 22:13:49
super
定义了它自己的一些属性,并且需要一种方法来提供对它们的访问。首先是使用__dunder__
样式,Python为自己保留了这种样式,并表示任何库或应用程序都不应该定义以双下划线开头和结尾的名称。这意味着super
对象可以确信没有任何内容会与其__self__
、__self_class__
和__thisclass__
属性冲突。因此,如果它搜索mro,但没有找到请求的属性,那么它就会返回到试图在超级对象本身上查找该属性。例如:
>>> class A:
pass
>>> class B(A):
pass
>>> s = super(A, B())
>>> s.__self__
<__main__.B object at 0x03BE4E70>
>>> s.__self_class__
<class '__main__.B'>
>>> s.__thisclass__
<class '__main__.A'>
由于您已经将object
指定为要开始查找的类型,并且object
始终是mro中的最后一个类型,因此不存在获取方法或属性的可能候选者。在这种情况下,super的行为就好像它尝试了各种类型来查找名称,但都没有找到。因此,它尝试从自身获取属性。但是,由于super
对象也是一个对象,因此它可以访问__init__
、__repr__
和object
定义的所有其他内容。因此super
会为您返回它自己的__init__
和__repr__
方法。
这是一种“问一个愚蠢的问题,然后得到一个愚蠢的答案”的情况。也就是说,只能使用定义函数的类的第一个参数来调用super
。当你用object
调用它时,你得到的是未定义的行为。
https://stackoverflow.com/questions/50656716
复制相似问题