CPython似乎将该类型<method-wrapper ..>
用于在 C 代码中实现的方法。基本上该类型不包装另一种方法。相反,它将 C 实现的函数包装为绑定方法。这种方式<method-wrapper>
与 a 完全一样,<bound-method>
只是它是用 C 实现的。
在 CPython 中有两种与此相关的特殊类型。
<slot wrapper>
其中(至少)包装了一个 C 实现的函数。表现得像<unbound method>
CPython 2 中的 a (至少有时)或<function>
CPython 3 中的 a
<method-wrapper>
它将 C 实现的函数包装为绑定方法。这种类型的实例有一个__self__
属性__,它在被调用时用作第一个参数。
如果您有 a <slot wrapper>
,则将其绑定到一个对象__get__
以获取<method-wrapper>
:
# returns a <slot_wrapper> on both CPython 2 and 3
sw = object.__getattribute__
# returns a <method-wrapper>
bound_method = sw.__get__(object())
# In this case raises AttributeError since no "some_attribute" exists.
bound_method("some_attribute")
您可以__get__
在 Python 中调用任何类似函数的对象来获取<bound method>
or <method-wrapper>
。注意__get__
这两种类型都会简单地返回 self。
蟒蛇 3
CPython 3 中的类型对and和任何其他比较运算符object
都有 C 实现。因此为此运算符返回 a 。同样返回可用于比较 this 对象的 a。__ne__
__eq__
object.__ne__
<slot wrapper>
object().__ne__
<method-wrapper>
由于您没有__ne__
在您的类中定义,您将获得一个绑定方法(as <method-wrapper>
),它是对象实例(包括派生实例)的 C 实现函数。我敢打赌,这个 C 函数将检查您是否定义了 any __eq__
,调用它,然后不检查结果。
Python 2(未问但已回答)
Python 2 在这里的表现明显不同。因为我们有未绑定方法的概念。这要求您使用正确的第一个参数类型来调用它们,并且两者<slot wrapper>
都有<method-wrapper>
一个__objclass__
which 是第一个参数必须是实例的类型。
此外:Python 2 没有该object
类型的比较运算符的任何实现。因此object.__ne__
不是比较对象的功能。相反,有趣的type
是,作为元类的类型object
确实有一个 C 实现的__ne__
运算符。因此,您将获得一个绑定方法,object.__ne__
该方法将尝试将该类型object
与任何其他类型(或对象)进行比较。
因此object().__ne__
实际上会失败,AttributeError
因为object
没有定义任何此类方法。鉴于这object() == object()
确实有效(给出 False),我猜想 CPython 2 在解释器中有用于比较对象的特殊情况。我们再次看到 CPython 3 已经清理了 Python 2 的一些不太幸运的实现细节。