Comparison methods

Edw88253 none at dev.null
Thu May 3 23:00:06 EDT 2001


I had two questions about Python's comparison methods (__cmp__, __eq__,
etc.):

================================
Question 1:

When defining __eq__ for classes, is there any "standard" result when two
objects are compared, and one's class is a superclass of the other?  I ask,
because initially I was defining __eq__ as:

def __eq__(self, other):
    if not isinstance(other, MyClass): return 0
    return <appropriate expression>

But, using that definition, a==b and b==a won't always return the same
thing, which is presumably a Bad Thing.

We could instead define __eq__ as:

def __eq__(self, other):
    if not isinstance(other, MyClass): return 0
    if other.__class__ != MyClass: return 0
    return <appropriate expression>

(i.e., two things can only be equal if they have the same class.)  Would
this be a "better" definition?  Is there a way to do this without using
double-underscored variables?

The other reasonable alternative I see is to have equality be based on the
higher of the two classes.  So we would define the child's __eq__ as
something like:

def __eq__(self, other):
    if not isinstance(other, MyClass): return NotImplemented
    return <appropraite expression>

Although I'm not sure whether that would interact with multiple inheritance
in undesirable ways..

Also, is it more conventional to return 0 or to raise a TypeError if an
object is compared to another object that's of different type?

================================
Question 2:

The __eq__, __gt__, etc. methods seem to be called more often than necessary
when I compare two objects.  Is this a bug or a feature?  (See transcript
below)  If it's a feature, what's it accomplishing?

class A:
    def __init__(self, c): self.c=c
    def __cmp__(s,o):
        print 'cmp', s.c, o.c
        return NotImplemented
    def __eq__(s,o):
        print 'eq', s.c, o.c
        return NotImplemented
    def __lt__(s,o):
        print 'lt', s.c, o.c
        return NotImplemented
    def __gt__(s,o):
        print 'gt', s.c, o.c
        return NotImplemented

>>> (a, b) = (A('a'), A('b'))
>>> a == b
eq a b
eq b a
eq b a
eq a b
cmp a b
cmp b a
0
>>> a < b
lt a b
gt b a
gt b a
lt a b
cmp a b
cmp b a
0

================================
Thanks
-Edward






More information about the Python-list mailing list