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
_______________________________________________
Python-3000 mailing list
Python-3000@python.org
http://mail.python.org/mailman/listinfo/python-3000
Unsubscribe:
http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com