[Python-Dev] == on object tests identity in 3.x
Andreas Maier
andreas.r.maier at gmx.de
Tue Jul 8 01:36:25 CEST 2014
Am 2014-07-07 19:43, schrieb Ethan Furman:
> On 07/07/2014 09:56 AM, Andreas Maier wrote:
>> Am 07.07.2014 17:55, schrieb Ethan Furman:
>>> On 07/07/2014 04:22 AM, Andreas Maier wrote:
>>>>
>>>> Where is the discrepancy between the documentation of == and its
>>>> default implementation on object documented?
>>>
>>> There's seems to be no discrepancy (at least, you have not shown it),
>>
>> The documentation states consistently that == tests the equality of
>> the value of an object. The default implementation
>> of == in both 2.x and 3.x tests the object identity. Is that not a
>> discrepancy?
>
> One could say that the value of an object is the object itself. Since
> different objects are different, then they are not equal.
>
>>> but to answer the question about why the default equals operation is an
>>> identity test:
>>>
>>> - all objects should be equal to themselves (there is only one that
>>> isn't, and it's weird)
>>
>> I agree. But that is not a reason to conclude that different objects
>> (as per their identity) should be unequal. Which is
>> what the default implementation does.
>
> Python cannot know which values are important in an equality test, and
> which are not. So it refuses to guess.
>
Well, one could argue that using the address of an object for its value
equality test is pretty close to guessing, considering that given a
sensible definition of value equality, objects of different identity can
very well be equal but will always be considered unequal based on the
address.
> Think of a chess board, for example. Are any two black pawns equal?
> All 16 pawns came from the same Pawn class, the only differences would
> be in the color and position, but the movement type is the same for all.
>
> So equality for a pawn might mean the same color, or it might mean
> color and position, or it might mean can move to the same position...
> it's up to the programmer to decide which of the possibilities is the
> correct one. Quite frankly, have equality mean identity in this case
> also makes a lot of sense.
That's why I think equality is only defined once the class designer has
defined it. Using the address as a default for equality (that is, in
absence of such a designer's definition) may be an easy-to-implement
default, but not a very logical or sensible one.
>
>>> - equality tests should not, as a general rule, raise exceptions --
>>> they should return True or False
>>
>> Why not? Ordering tests also raise exceptions if ordering is not
>> implemented.
>
> Besides the pawn example, this is probably a matter of practicality
> over purity -- equality tests are used extensively through-out Python,
> and having exceptions raised at possibly any moment would not be a fun
> nor productive environment.
>
So we have many cases of classes whose designers thought about whether a
sensible definition of equality was needed, and decided that an
address/identity-based equality definition was just what they needed,
yet they did not want to or could not use the "is" operator?
Can you give me an example for such a class (besides type object)? (I.e.
a class that does not have __eq__() and __ne__() but whose instances are
compared with == or !=)
> Ordering is much less frequent, and since we already tried always
> ordering things, falling back to type name if necessary, we have
> discovered that that is not a good trade-off. So now if one tries to
> order things without specifying how it should be done, one gets an
> exception.
In Python 2, the default ordering implementation on type object uses the
identity (address) as the basis for ordering. In Python 3, that was
changed to raise an exception. That seems to be in sync with what you
are saying.
Maybe it would have been possible to also change that for the default
equality implementation in Python 3. But it was not changed. As I wrote
in another response, we now need to document this properly.
More information about the Python-Dev
mailing list