python中super(type,object)和super(supertype,type)之间有什么区别?

dsp*_*pjm 2 python inheritance class super

不会super(type, object)super(supertype, type)所有人都返回超类的对象type(supertype)吗?有什么不同?

Mar*_*ers 5

差异很大; super()使用类型(类)第二个参数而不是对象(实例)为您提供未绑定的方法,而不是绑定的方法(就像访问类上的那些方法一样).

我将首先解释如何super()使用实例第二个参数.

super()检查MRO self,找到MRO中的第一个参数(typesupertype),然后找到具有所请求属性的下一个对象.

演示:

>>> class BaseClass(object):
...     def foo(self): return 'BaseClass foo'
... 
>>> class Intermediary(BaseClass):
...     def foo(self): return 'Intermediary foo'
... 
>>> class Derived(Intermediary):
...     def foo(self): return 'Derived foo'
... 
>>> d = Derived()
>>> d.foo()
'Derived foo'
>>> super(Derived, d).foo
<bound method Derived.foo of <__main__.Derived object at 0x10ef4de90>>
>>> super(Derived, d).foo()
'Intermediary foo'
>>> super(Intermediary, d).foo()
'BaseClass foo'
>>> Derived.__mro__
(<class '__main__.Derived'>, <class '__main__.Intermediary'>, <class '__main__.BaseClass'>, <type 'object'>)
Run Code Online (Sandbox Code Playgroud)

MRO Derived(Derived, Intermediary, BaseClass); super()通过查看第二个参数,找到这个MRO type(d).__mro__.foo在给出第一个参数后,在下一个类中搜索开始.

这个foo()方法绑定在这里,你可以调用它.

如果你给super()一个类型作为第二个参数,那么它将使用该类型的MRO,例如,而不是使用type(instance).__mro__它只是去type.__mro__.但是它没有将方法绑定到的实例.super(supertype, type).foo绑定:

>>> super(Intermediary, Derived).foo
<unbound method Derived.foo>
>>> super(Intermediary, Derived).foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unbound method foo() must be called with Derived instance as first argument (got nothing instead)
>>> super(Intermediary, Derived).foo(d)
'BaseClass foo'
Run Code Online (Sandbox Code Playgroud)

要调用.foo()我必须显式传入一个self参数.

(在Python 3中,上面将返回foo函数对象而不是未绑定的方法,但原理是相同的).

返回的方法也是来自MRO链中的下一个类; BaseClass.foo被送回那里.

这取决于function.__get__方法(即描述符协议,负责绑定),因为它在传递要绑定的类时返回未绑定的对象(Python 2中的未绑定方法,Python 3中的函数本身).(对于classmethod对象,__get__在类中传递时返回绑定对象).

因此,TL; DR,for方法super(type, object)返回绑定方法,super(supertype, type)返回未绑定方法.