Python 3.6.5 “is” and “==” for integers beyond caching interval [duplicate]

纵然是瞬间 提交于 2019-12-05 13:04:39
Aran-Fey

CPython detects constant values in your code and re-uses them to save memory. These constants are stored on code objects, and can even be accessed from within python:

>>> codeobj = compile('999 is 999', '<stdin>', 'exec')
>>> codeobj
<code object <module> at 0x7fec489ef420, file "<stdin>", line 1>
>>> codeobj.co_consts
(999, None)

Both operands of your is refer to this very same 999 integer. We can confirm this by dissecting the code with the dis module:

>>> dis.dis(codeobj)
  1           0 LOAD_CONST               0 (999)
              2 LOAD_CONST               0 (999)
              4 COMPARE_OP               8 (is)
              6 POP_TOP
              8 LOAD_CONST               1 (None)
             10 RETURN_VALUE

As you can see, the first two LOAD_CONST instructions both load the constant with index 0, which is the 999 number.

However, this only happens if the two numbers are compiled at the same time. If you create each number in a separate code object, they will no longer be identical:

>>> x = 999
>>> x is 999
False

Remember that Python is compiled. The expression was compiled all at once and its literals are shared when possible. Any operation, like your exponentiation, or adding and subtracting 1 from one side, will break the identity. (Python could in theory do constant folding and thereby extend the set of is-identical expressions, but it doesn’t bother.)

Performing multiple compilations will also break this:

>>> x=300
>>> x is 300
False
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!