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