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

Rob Cliffe rob.cliffe at btinternet.com
Tue Jul 8 06:02:39 CEST 2014


On 08/07/2014 04:12, Steven D'Aprano wrote:
> On Tue, Jul 08, 2014 at 02:59:30AM +0100, Rob Cliffe wrote:
>
>>> - "*Every object has an identity, a type and a value.*"
>> Hm, is that *really* true?
> Yes. It's pretty much true by definition: objects are *defined* to have
> an identity, type and value, even if that value is abstract rather than
> concrete.
Except that in your last paragraph you imply that an explicit 
*definition* of the value is normally not in the docs.
>
>
>> 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? :-) )
> I don't think so. Variables can be undefined, which means they don't
> have a value:
>
> py> del x
> py> print x
> Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
> NameError: name 'x' is not defined
I was aware of that but I considered that a deleted variable no longer 
existed.  Not that it's important.
>
>
>> But ISTM that the notion of the value of an *object* exists more in our
>> minds than in Python.
> Pretty much. How could it be otherwise? Human beings define the
> semantics of objects, that is, their value, not Python.
>
>
> [...]
>> 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?
> You couldn't, any more than you would know what the value of a Watzit
> object was if you knew nothing about Watzits. The value of an object is
> intimitely tied to its semantics, what the object represents and what it
> is intended to be used for. In general, we can say nothing about the
> value of an object until we've read the documentation for the object.
>
> But we can be confident that the object has *some* value, otherwise what
> would be the point of it? In some cases, that value might be nothing
> more than it's identity, but that's okay.
>
> I think the problem we're having here is that some people are looking
> for a concrete definition of what the value of an object is, but there
> isn't one.
>
>
> [...]
>> 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)
> The value as understood by a human reader, as opposed to the value as
> assumed by Python, is not necessarily the same. As far as Python is
> concerned, the value of all four objects is the object itself, i.e. its
> identity.
Is this mentioned in the docs?  I couldn't find it in a quick look 
through the 2.7.8 language reference.

> (For avoidance of doubt, not its id(), which is just a
> number.)
>
> A human reader could infer more than Python:
>
> - the second object is a "do nothing" function;
> - the third object is a lazy sequence (0, 1, 2);
> - the fourth object is a lazy sequence (0, 1, 2, 3);
>
> but since the class designer didn't deem it important enough, or
> practical enough, to implement an __eq__ method that takes those things
> into account, *for the purposes of equality* (but perhaps not other
> purposes) we say that the value is just the object itself, its identity.
>
>
>
>> 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?
> In principle, one might peer into the two generators and note that they
> perform exactly the same computations on exactly the same input, and
> therefore should be deemed to have the same value. But since that's
> hard, and "exactly the same" is not always well-defined, Python doesn't
> try to be too clever and just uses a simpler idea: the value is the
> object itself.
Sure, I wasn't suggesting it was a sensible thing to do (quite the 
opposite), just playing devil's advocate.
>
>
>> 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.).
> Generator objects have code objects as well.
>
> py> x = (a for a in (1, 2))
> py> x.gi_code
> <code object <genexpr> at 0xb7ee39f8, file "<stdin>", line 1>
>
>>> - "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.
> Why? What value (pun intended) is there in adding an explicit statement
> of value to every single class?
It troubles me a bit that "value" seems to be a fuzzy concept - it has 
an obvious meaning for some types (int, float, list etc.) but for 
callable objects you tell me that their value is the object itself, but 
I can't find it in the docs.  (Is the same true for module objects?)
Apart from anything else:

"Objects whose value can change
are said to be mutable"

How can we say if an object is mutable if we don't know what its value is?
Are callables non-mutable?  (Presumably?)
What about modules?  (Their *attributes* can be changed.)
Or are these questions considered stupid and/or irrelevant?

>
> "The value of a str is the str's sequence of characters."
> "The value of a list is the list's sequence of items."
> "The value of an int is the int's numeric value."
> "The value of a float is the float's numeric value, or in the case of
>   INFs and NANs, that they are an INF or NAN."
> "The value of a complex number is the ordered pair of its real and
>   imaginary components."
> "The value of a re MatchObject is the MatchObject itself."
>
> I don't see any benefit to forcing all classes to explicitly document
> this sort of thing. It's nearly always redundant and unnecessary.
>
"nearly always" yes, but there might be one or two cases where it would 
help.  Sorry, I don't have an example at present.

Thanks for a very full answer, Steven.
Rob Cliffe



More information about the Python-Dev mailing list