Rich Comparisons Gotcha
steven at REMOVE.THIS.cybersource.com.au
Thu Dec 11 09:10:12 CET 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)
> 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:
if obj in list_of_bad_types_i_know_about:
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.
More information about the Python-list