Why do these statements evaluate the way they do?

Steven D'Aprano steve at pearwood.info
Sat May 7 06:05:15 EDT 2016


On Sat, 7 May 2016 04:36 pm, Anthony Papillion wrote:

> I'm trying to figure out why the following statements evaluate the way
> they do and I'm not grasping it for some reason. I'm hoping someone can
> help me.
> 
> 40+2 is 42 #evaluates to True
> But
> 2**32 is 2**32 #evaluates to False

That is not a guarantee of the language, it is an implementation detail.

The only language guarantee is that:

40 + 2 == 42

which MUST be true. But the Python interpreter has a choice here:

- it can create *two* distinct int objects with value 42;

- or it can cache the int object and re-use it.

In the first case, `40 + 2 is 42` will return False. In the second case, it
will return True.

Remember that `is` does not test for equality, it checks for object
identity, namely, "are the two objects one and the same object?"

The standard Python interpreter caches "small integers". The definition
of "small" depends on the version, but 42 is included, and 2**32 is not. So
you may find that

40 + 2 is 42

re-uses the same cached object and returns True, but

2**32 is 2**32

creates a new int object each time and returns False.


The lesson here is:

(1) ** NEVER ** use `is` to test for equality. The `is` operator is not a
funny well of spelling == it is a completely different operator that tests
for object identity.

(2) You cannot rely on Python object caches, as that is implementation and
version dependent. It is an optimization, to speed up some arithmetic at
the expense of using a little more memory.

(3) Almost the only acceptable use for `is` is to test for the singleton
object None. (There are other uses, but they are unusual and testing for
None is common. Always write:

    if obj is None: ...

rather than:

    if obj == None: ...


But for (nearly) everything else, always use == equality.




-- 
Steven




More information about the Python-list mailing list