[Python-Dev] == on object tests identity in 3.x

Rob Cliffe rob.cliffe at btinternet.com
Tue Jul 8 03:59:30 CEST 2014


On 08/07/2014 00:37, Andreas Maier wrote:
> [...]
> Am 2014-07-07 23:11, schrieb Jan Kaliszewski:
>>
>> IMHO, in Python context, "value" is a very vague term.  Quite often 
>> we can read it as the very basic (but not the only one) notion of 
>> "what makes objects being equal or not" -- and then saying that 
>> "objects are compared by value" is a tautology.
>>
>> In other words, what object's "value" is -- is dependent on its 
>> nature: e.g. the value of a list is what are the values of its 
>> consecutive (indexed) items; the value of a set is based on values of 
>> all its elements without notion of order or repetition; the value of 
>> a number is a set of its abstract mathematical properties that 
>> determine what makes objects being equal, greater, lesser, how 
>> particular arithmetic operations work etc...
>>
>> I think, there is no universal notion of "the value of a Python 
>> object".  The notion of identity seems to be most generic (every 
>> object has it, event if it does not have any other property) -- and 
>> that's why by default it is used to define the most basic feature of 
>> object's *value*, i.e. "what makes objects being equal or not" (== 
>> and !=).  Another possibility would be to raise TypeError but, as 
>> Ethan Furman wrote, it would be impractical (e.g. 
>> key-type-heterogenic dicts or sets would be practically impossible to 
>> work with). On the other hand, the notion of sorting order (< > <= 
>> >=) is a much more specialized object property.
>
+1.  See below.
> On the universal notion of a value in Python: In both 2.x and 3.x, it 
> reads (in 3.1. Objects, values and types):
> - "*Every object has an identity, a type and a value.*"
Hm, is that *really* true?
Every object has an identity and a type, sure.
Every *variable* has a value, which is an object (an instance of some 
class).  (I think? :-) )
But ISTM that the notion of the value of an *object* exists more in our 
minds than in Python.  We say that number and string objects have a 
value because the concepts of number and string, including how to 
compare them, are intuitive for us, and these objects by design reflect 
our concepts with some degree of fidelity.  Ditto for lists, 
dictionaries and sets which are only slightly less intuitive.

If I came across an int object and had no concept of what an integer 
number was, how would I know what its "value" is supposed to be?
If I'm given an int object, "i", say, and pretend I don't know what an 
integer is, I see that
     len(dir(i)) == 64    # Python 2.7
(and there may be attributes that dir doesn't show).
How can I know from this bewildering list of 64 attributes (say they 
were all written in Swahili) that I can obtain the "real" (pun not 
intended) "value" with
     i.real
or possibly
     i.numerator
or
     i.__str__()
or maybe somewhere else?  ISTM "value" is a convention between humans, 
not something intrinsic to a class definition.  Or at best something 
that is implied by the implementation of the comparison (or other) 
operators in the class.

And can the following *objects* (class instances) be said to have a 
(obvious) value?
     obj1 = object()
     def obj2(): pass
     obj3 = (x for x in range(3))
     obj4 = xrange(4)
And is there any sensible way of comparing two such similar objects, e.g.
     obj3  = (x for x in range(3))
     obj3a = (x for x in range(3))
except by id?
Well, possibly in some cases.  You might define two functions as equal 
if their code objects are identical (I'm outside my competence here, so 
please no-one correct me if I've got the technical detail wrong).  But I 
don't see how you can compare two generators (other than by id) except 
by calling them both destructively (possibly an infinite number of 
times, and hoping that neither has unpredictable behaviour, side 
effects, etc.).
As has already been said (more or less) in this thread, if you want to 
be able to compare any two objects of the same type, and not by id, you 
probably end up with a circular definition of "value" as "that (function 
of an object's attributes) which is compared". Which is ultimately an 
implementation decision for each type, not anything intrinsic to the type.
So it makes sense to consistently fall back on id when nothing else 
obvious suggests itself.

> - "An object's /identity/ never changes once it has been created; .... 
> The /value/ of some objects can change. Objects whose value can change 
> are said to be /mutable/; objects whose value is unchangeable once 
> they are created are called /immutable/."
ISTM it needs to be explicitly documented for each class what the 
"value" of an instance is intended to be.  Oh, I'm being pedantic here, 
sure.  But I wonder if enforcing it would lead to more clarity of 
thought (maybe even the realisation that some objects don't have a 
value?? :-) ).

>
> These are clear indications that there is an intention to have 
> separate concepts of identity and value in Python. If an instance of 
> type object can exist but does not have a universal notion of value, 
> it should not allow operations that need a value.
As Jan says, this would make comparing container objects a pain.

Apologies if this message is a bit behind the times.  There have been 
about 10 contributions since I started composing this!
Best wishes,
Rob Cliffe


[...]
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20140708/91ab3b74/attachment.html>


More information about the Python-Dev mailing list