A name refers to an object, an object has a value, equality compares values

Chris Angelico rosuav at gmail.com
Wed Nov 25 03:27:47 EST 2015


On Wed, Nov 25, 2015 at 5:44 PM, Marko Rauhamaa <marko at pacujo.net> wrote:
> I don't think the meaning of the word "value" can be restricted in that
> way. Let's try to "refactor" the examples I had found in the wild:
>
>   "How to get the value of a variable given its name in a string"
>   => How to get the object a variable is bound to given the name of the
>      variable in a string
>
>   "The value of some objects can change. Objects whose value can change
>   are said to be mutable"
>   [no change]

Agree with these.

>   "I'm taking the return value of one function and using it as the
>   argument of another function"
>   => I'm taking the return object of one function and using it as the
>      argument of another function
>
>   "Don't get confused — name on the left, value on the right"
>   => Don't get confused — name on the left, object on the right
>
>   "A return statement ends the execution of the function call and
>   "returns" the result, i.e. the value of the expression following the
>   return keyword, to the caller"
>   => A return statement ends the execution of the function call and
>      "returns" the result, i.e. the resulting object of the expression
>      following the return keyword, to the caller
>
>   "When we ask python what the value of x > 5 is, we get False"
>   => When we ask python what the resulting object of x > 5 is, we get
>      False

These are all talking about the value of an expression. Expressions
have values, just as objects do; in Python, evaluation of an
expression results in some object whose value is the value of the
expression. In many cases, the definition of an expression's value has
nothing to do with object identity, only value - for instance, when
you call methods on strings such as lower(), center(), or format(),
they're required to return a string object with a particular value,
but there's no rule about that object's identity. On the CPython that
I tried:

$ python3
Python 3.4.2 (default, Oct  8 2014, 10:45:20)
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> s = "hello world"
>>> s.lower() is s
False
>>> s.center(len(s)) is s
True
>>> s.format() is s
True

A compliant Python would be allowed to return either True or False for
each of these; but if you change the 'is' checks to '==', they have to
all be True, because the given operations don't change the string's
*value* at all. Same with integer arithmetic, string concatenation,
and so on.

>   "To display the value of a variable, you can use a print statement"
>   => To display the value of the object a variable is bound to, you can
>      use a print statement

This one was probably talking to a new programmer. It's often not
worth going into extreme detail early on; being slightly sloppy with
terminology isn't a problem when what you're really saying is just
"use print to find out what your program is doing".

>   "Get a value of a specified key"
>   => Get an image object of a specified key

Another one that's looking at the value of an expression. In this
case, though, the value is defined based on object identity as well as
value, so I suppose you could word this as:

"Get the object referenced by a specified key"

if you wanted to be pedantic. But dictionaries are defined as mapping
keys to values, and the value associated with a key happens to be
represented by some object.

> In a word, it's a lost cause.

Doesn't need to be.

> It is actually somewhat comical how Python documentation tries, but
> fails, to maintain terminological orthodoxy:
>
>   A mapping object maps hashable values to arbitrary objects. [...]
>
>   A dictionary’s keys are almost arbitrary values. Values that are not
>   hashable, that is, values containing lists, dictionaries or other
>   mutable types (that are compared by value rather than by object
>   identity) may not be used as keys.

No, this is strictly correct. A dictionary's keys are defined by
values, not objects. The dict retains references to the objects used,
but it's equality, not identity, that defines the match.

>>> class S(str): pass
...
>>> k1 = S("hello")
>>> k2 = S("hello")
>>> k1 is k2
False
>>> k1 == k2
True
>>> d = {k1: 42}
>>> d[k2]
42

The *value* of the setter key is what the dictionary cares about,
although it does retain the identity of the object:

>>> next(iter(d)) is k1
True

>   Dictionaries can be created by placing a comma-separated list of
>   key: value pairs within braces
>
>   [...]
>
>   The first object of each item becomes a key in the new dictionary, and
>   the second object the corresponding value. If a key occurs more than
>   once, the last value for that key becomes the corresponding value in
>   the new dictionary.
>
>   [...]
>
>   d[key] = value
>     Set d[key] to value.
>
>   [...]
>
>   values()
>     Return a new view of the dictionary’s values.
>
>   <URL: https://docs.python.org/3/library/stdtypes.html?highlig
>   ht=value#mapping-types-dict>

These are all talking about the other sense of "value" - the way
expressions yield values. If you were to build a binary tree in
Python, you'd have a similar concept of the nodes' "values", which
would again be represented by Python objects; but to the tree, they're
values. It's equivocation on the word "value", but I don't know of a
better word for it (I've sometimes used "payload", but that has its
own issues).

ChrisA



More information about the Python-list mailing list