[Python-3000] A plus for naked unbound methods
Terry Reedy
tjreedy at udel.edu
Tue Oct 7 17:44:24 CEST 2008
Nick Coghlan wrote:
> (added Michael to the CC list)
>
> It isn't object that has grown an __lt__ method, but type. The extra
> check Michael actually wants is a way to make sure that the method isn't
> coming from the object's metaclass, and the only reliable way to do that
> is the way collections.Hashable does it when looking for __hash__:
> iterate through the MRO looking for that method name in the class
> dictionaries
Thank you for the explanation. I was aware that MRO traversal should be
the 'officially correct' procedure for the original, but did not
understand why (for 2.x, at least).
> In the case of the comparison methods, they're being retrieved from type
> rather than object. This difference is made clear when you attempt to
> invoke the retrieved method:
>
>>>> object.__cmp__(1, 2)
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> TypeError: expected 1 arguments, got 2
>>>> object.__cmp__(2)
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> TypeError: type.__cmp__(x,y) requires y to be a 'type', not a 'int'
>>>> object.__cmp__(object)
> 0
This surprises me, partly because the situation seems to be different in
3.0. Using __le__ in place of the non-existent __cmp__,
>>> ole = object.__le__
>>> ole(1,2)
NotImplemented
>>> ole(1)
Traceback (most recent call last):
File "<pyshell#21>", line 1, in <module>
ole(1)
TypeError: expected 1 arguments, got 0
>>> ole(object)
Traceback (most recent call last):
File "<pyshell#22>", line 1, in <module>
ole(object)
TypeError: expected 1 arguments, got 0
>>> ole
<slot wrapper '__le__' of 'object' objects>
>>> dir(ole)
['__call__', '__class__', '__delattr__', '__doc__', '__eq__',
'__format__', '__ge__', '__get__', '__getattribute__', '__gt__',
'__hash__', '__init__', '__le__', '__lt__', '__name__', '__ne__',
'__new__', '__objclass__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__']
# no __self__ attribute
>>> class C(object): pass
>>> C.__le__
<slot wrapper '__le__' of 'object' objects>
# same as for hash in 2.5
I interpret all this to mean that in 3.0, rich comparison *are* defined
on and being retrieved from object. Correct?
I presume the change is because in 3.0, everything is an instance of
object, so all classes can inherit the common methods from object,
whereas that was *not* true in 2.x. I very much like the cleaner design.
Terry Jan Reedy
More information about the Python-3000
mailing list