Why keep identity-based equality comparison?

Noam Raphael spam.noam at gmail.com
Sat Jan 14 20:02:40 EST 2006


Mike Meyer wrote:
> Noam Raphael <spam.noam at gmail.com> writes:
> 
>>>>Also note that using the current behaviour, you can't easily
>>>>treat objects that do define a meaningful value comparison, by
>>>>identity.
>>>
>>>Yes you can. Just use the "is" operator.
>>
>>Sorry, I wasn't clear enough. In "treating" I meant how containers
>>treat the objects they contain. For example, you can't easily map a
>>value to a specific instance of a list - dict only lets you map a
>>value to a specific *value* of a list.
> 
> 
> Wrong. All you have to do is create a list type that uses identity
> instead of value for equality testing. This is easier than mapping an
> exception to false.
> 
You're suggesting a workaround, which requires me to subclass everything 
that I want to lookup by identity (and don't think it's simple - I will 
have to wrap a lot of methods that return a list to return a list with a 
modified == operator).

I'm suggesting the use of another container class: iddict instead of 
dict. That's all.
I don't think that mapping an exception to false is so hard (certainly 
simpler than subclassing a list in that way), and the average user won't 
have to do it, anyway - it's the list implementation that will do it.
> 
>>Another example - you can't
>>search for a specific list object in another list.
> 
> 
> Your proposed == behavior doesn't change that at all.

It does - *use idlist*.
> 
> 
>>>I will point out why your example usages aren't really usefull if
>>>you'll repeat your post with newlines.
>>
>>Here they are:
>>* Things like "Decimal(3.0) == 3.0" will make more sense (raise an
>>exception which explains that decimals should not be compared to
>>floats, instead of returning False).
> 
> 
> While I agree that Decimal(3.0) == 3.0 returning false doesn't make
> sense, having it raise an exception doesn't make any more sense. This
> should be fixed, but changing == doesn't fix it.
> 
No, it can't be fixed your way. It was decided on purpose that Decimal 
shouldn't be comparable to float, to prevent precision errors. I'm 
saying that raising an exception will make it clearer.
> 
>>* You won't be able to use objects as keys, expecting them to be
>>compared by value, and causing a bug when they don't. I recently wrote
>>a sort-of OCR program, which contains a mapping from a numarray array
>>of bits to a character (the array is the pixel-image of the char).
>>Everything seemed to work, but the program didn't recognize any
>>characters. I discovered that the reason was that arrays are hashed
>>according to their identity, which is a thing I had to guess. If
>>default == operator were not defined, I would simply get a TypeError
>>immediately.
> 
> 
> This isn't a use case. You don't get correct code with either version
> of '=='. While there is some merit to doing things that make errors
> easier to find, Python in general rejects the idea of adding
> boilerplate to do so. Your proposal would generate lots of boilerplate
> for many practical situations.
> 
I would say that there's a lot of merit to doing things that make errors 
easier to find. That's what exceptions are for.

Please say what those practical situations are - that what I want.
(I understand. You think that added containers and a try...except  fro 
time to time aren't worth it. I think they are. Do you have any other 
practical situations?)
> 
>>* It is more forward compatible - when it is discovered that two types
>>can sensibly be compared, the comparison can be defined, without
>>changing an existing behaviour which doesn't raise an exception.
> 
> 
> Sorry, but that doesn't fly. If you have code that relies on the
> exception being raised when two types are compared, changing it to
> suddenly return a boolean will break that code.
> 
You are right, but that's the case for every added language feature (if 
you add a method, you break code that relies on an AttributeError...)
You are right that I'm suggesting a try...except when testing if a list 
contains an object, but a case when you have a list with floats and 
Decimals, and you rely on "Decimal("3.0") in list1" to find only 
Decimals seems to me a little bit far-fetched. If you have another 
example, please say it.

Noam



More information about the Python-list mailing list