On Fri, Jul 7, 2017 at 5:29 PM, Dan Wissme <wis...@free.fr> wrote:
> Strange behavior in Python 3.6.0
>>>> i = 3000
>>>> j = 3000
>>>> i is j
> False
>>>> n = 4000 ; m = 4000 ; n is m
> True

Firstly, remember that immutables are allowed, but not required, to be
shared. So this kind of "strange behaviour" is completely fine - and
furthermore, can come and go at any time.

What you're seeing here is an artifact of the interactive interpreter.
Each statement or block that you enter gets compiled and executed on
its own. When you do the last block, the compiler looks at the whole
thing, and produces this code:

>>> c = compile("n = 4000 ; m = 4000 ; n is m", "<stdin>", "single")
>>> c.co_consts
(4000, None)
>>> dis.dis(c)
  1           0 LOAD_CONST               0 (4000)
              2 STORE_NAME               0 (n)
              4 LOAD_CONST               0 (4000)
              6 STORE_NAME               1 (m)
              8 LOAD_NAME                0 (n)
             10 LOAD_NAME                1 (m)
             12 COMPARE_OP               8 (is)
             14 PRINT_EXPR
             16 LOAD_CONST               1 (None)
             18 RETURN_VALUE

The print and return at the end are how the REPL works. The rest is your code.

The compiler noticed that it needed to load the constant integer 4000
twice, so it put it into the co_consts collection once and used the
same integer object each time.

Armed with that information, it should be easy to see why your 3000
example returned False. Each of the assignments was compiled
separately, and the compiler didn't look at previous compilations to
reuse an integer. Thus the two are separate objects. The compiler
COULD, if it felt like it, reuse that; conversely, a naive and
inefficient compiler is welcome to generate brand new integers for n
and m. Actually, I believe a compliant Python interpreter is welcome
to not store integer objects in memory at all, as long as it can
guarantee the correct identity semantics (eg the 'is' and 'is not'
operators on integers would be defined on value, and id(x) would
return x*2+1 for ints and even numbers for other objects), although I
don't know of any implementations that do this.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list

Reply via email to