Rich Comparisons Gotcha

Steven D'Aprano steven at REMOVE.THIS.cybersource.com.au
Thu Dec 11 03:10:12 EST 2008


On Wed, 10 Dec 2008 17:58:49 -0500, Luis Zarrabeitia wrote:

> On Sunday 07 December 2008 09:21:18 pm Robert Kern wrote:
>> The deficiency is in the feature of rich comparisons, not numpy's
>> implementation of it. __eq__() is allowed to return non-booleans;
>> however, there are some parts of Python's implementation like
>> list.__contains__() that still expect the return value of __eq__() to
>> be meaningfully cast to a boolean.
> 
> list.__contains__, tuple.__contains__, the 'if' keyword...
> 
> How do can you suggest to fix the list.__contains__ implementation?


I suggest you don't, because I don't think it's broken. I think it's 
working as designed. It doesn't succeed with arbitrary data types which 
may be broken, buggy or incompatible with __contain__'s design, but 
that's okay, it's not supposed to.


> Should I wrap all my "if"s with this?:
> 
> if isinstance(a, numpy.array) or isisntance(b,numpy.array):
>     res = compare_numpy(a,b)
> elif isinstance(a,some_otherclass) or isinstance(b,someotherclass):
>     res = compare_someotherclass(a,b)
> ...
> else:
>     res = (a == b)
> if res:
>    # do whatever

No, inlining that code everywhere you have an if would be stupid. What 
you should do is write a single function equals(x, y) that does precisely 
what you want it to do, in whatever way you want, and then call it:

if equals(a, b):

Or, put your data inside a wrapper. If you read back over my earlier 
posts in this thread, I suggested a lightweight wrapper class you could 
use. You could make it even more useful by using delegation to make the 
wrapped class behave *exactly* like the original, except for __eq__.

You don't even need to wrap every single item:

def wrap_or_not(obj):
    if obj in list_of_bad_types_i_know_about:
        return EqualityWrapper(obj)
    return obj

data = [1, 2, 3, BadData, 4]
data = map(wrap_or_not, data)



It isn't really that hard to deal with these things, once you give up the 
illusion that your code should automatically work with arbitrarily wacky 
data types that you don't control.


-- 
Steven



More information about the Python-list mailing list