It appears that the type <method-wrapper ..>
is used by CPython for methods implemented in C code. Basically the type doesn't wrap another method. Instead it wraps a C-implemented function as an bound method. In this way <method-wrapper>
is exactly like a <bound-method>
except that it is implemented in C.
In CPython there are two special types related to this.
<slot wrapper>
Which (at least) wraps a C-implemented function. Behaves like an <unbound method>
in CPython 2 (at least sometimes) or a <function>
in CPython 3
<method-wrapper>
Which wraps a C-implemented function as an bound method. Instances of this type have an __self__
attribute__ which is used as first argument when it is called.
If you have a <slot wrapper>
you bind it to an object with __get__
to get an <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")
You can call __get__
on any function-like object in Python to get an <bound method>
or <method-wrapper>
. Note __get__
on both of these types will simply return self.
Python 3
The type object
in CPython 3 have C-implementations for both __ne__
and __eq__
, and any of the other comparison operators. Thus object.__ne__
returns a <slot wrapper>
for this operator. Likewise object().__ne__
returns a <method-wrapper>
which can be used to compare the this object.
Since you have not defined __ne__
in your class you get a bound method (as <method-wrapper>
) which is the C-implemented function for instance of object (included derived instances). My bet is that this C function will check if you have defined any __eq__
, call this, and then not the result.
Python 2 (not asked but answered)
Python 2 behaves significantly different here. Since we have the concept of unbound methods. which require that you call them with the proper first-argument type, both <slot wrapper>
and <method-wrapper>
have an __objclass__
which is the type the first-argument must be an instance of.
More over: Python 2 does not have any implementations of comparisons operators for the object
type. Thus object.__ne__
is not a function to compare objects. Rather, interesting, the type type
which is the metaclass of object
does have an C-implemented __ne__
operator. Thus you get an bound method from object.__ne__
that will try to compare the type object
with any other type (or object).
Thus object().__ne__
will actually fail with an AttributeError
since object
does not define any such method. Given that object() == object()
actually works (giving False), I would guess that CPython 2 have special-cases in the interpreter for comparison of objects.
Once more we see that CPython 3 have cleaned up some less-fortunate implementation details of Python 2.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…