Explaining names vs variables in Python

Jussi Piitulainen jussi.piitulainen at helsinki.fi
Wed Mar 2 10:37:57 EST 2016


Ian Kelly writes:

> On Wed, Mar 2, 2016 at 2:35 AM, Jussi Piitulainen wrote:
>> The following are too delicate for me. I suppose the answers could have
>> been different, but I can't guess what mechanism actually leads to these
>> results. Just idle curiosity on my part.
>>
>>>>> 890 is 890
>> True
>>>>> id(890) == id(890)
>> True
>
> This has to do with the way code blocks are compiled. In the
> interactive interpreter, a single line like '890 is 890' is compiled
> to a single code object. The constant 890 appears twice in the same
> code block, so the optimizer uses the same constant for both. Note in
> the following that the same index appears for both, so they're
> actually the same object reference.

No wonder my guesses failed. This is different.

>>>> import dis
>>>> dis.dis('890 is 890')
>   1           0 LOAD_CONST               0 (890)
>               3 LOAD_CONST               0 (890)
>               6 COMPARE_OP               8 (is)
>               9 RETURN_VALUE
>>>> compile('890 is 890', '', 'exec').co_consts
> (890, None)
>
>
> As for the earlier example of:
>
>>>>> 1 + 1 is 2
>> True
>>>>> 800 + 90 + 0 is 890
>> False
>
> This one actually surprises me a little, because the optimizer is also
> smart enough to evaluate '800 + 90 + 0' and just store a constant of
> 890:
>
>>>> dis.dis('800 + 90 + 0 is 890')
>   1           0 LOAD_CONST               5 (890)
>               3 LOAD_CONST               3 (890)
>               6 COMPARE_OP               8 (is)
>               9 RETURN_VALUE
>>>> compile('800 + 90 + 0 is 890', '', 'exec').co_consts
> (800, 90, 0, 890, None, 890, 890)
>
> Not smart enough to reuse the existing reference in this case
> apparently, or even to prune out the original constants that are no
> longer used in the code.

So it has access to three 890-objects and compares two of them :)

Thanks.



More information about the Python-list mailing list