【问题标题】:Why does '20000 is 20000' result in True? [duplicate]为什么“20000 是 20000”的结果为 True? [复制]
【发布时间】:2016-09-05 18:57:48
【问题描述】:

is 在 Python 中测试 2 个引用是否指向同一个对象。 -5 到 256 之间的数字在内部缓存,因此:

a = 10
b = 10
a is b # Results in True

这如何解释如下:

20000 is 20000 # Results in True

这两个数字都在 256 以上。 2 个整数不应该是 2 个不同的对象吗?

【问题讨论】:

  • 请注意: 1. 这不能保证,因此会因解释器/实现而异;和 2. 没有真正意义上的语义,你想知道 数字是否相等,而不是它们是否是同一个对象。

标签: python python-2.7 int literals python-internals


【解决方案1】:

Python 解释器看到您正在重用一个不可变对象,因此它不会费心创建两个:

>>> import dis
>>> dis.dis(compile('20000 is 20000', '', 'exec'))
  1           0 LOAD_CONST               0 (20000)
              3 LOAD_CONST               0 (20000)
              6 COMPARE_OP               8 (is)
              9 POP_TOP
             10 LOAD_CONST               1 (None)
             13 RETURN_VALUE

注意两个LOAD_CONST 操作码,它们都在索引0 处加载常量:

>>> compile('20000 is 20000', '', 'exec').co_consts
(20000, None)

在交互式解释器中,Python 仅限于必须编译您单独输入的每个(简单或复合)语句,因此它不能在不同的语句中重用这些常量。

但是在一个函数对象中它肯定只会创建一个这样的整数对象,即使你多次使用相同的 int 字面量。这同样适用于在 模块级别 运行的任何代码(因此在函数或类定义之外);这些也都以相同的代码对象常量结束。

【讨论】:

  • 那么在什么情况下 Python 只会创建一个对象呢?仅当两个整数都在同一行中使用时?执行a = 20000; b = 20000; a is b 会产生一个对象,但将 2 个分配放在 2 个单独的行上会产生两个对象。这真的是 Python 开发人员想要的吗?
  • @Tal:在交互式解释器中,只有当它们被编译在一起时,如果你把所有东西放在一行或一个复合语句中,就会发生这种情况。在脚本中(所以不在交互式解释器中),如果在同一个函数、类体或模块级别。
【解决方案2】:

Python 将对象存储在内存中以提高效率。它只需要给20000分配一块内存,所以两个引用都指向同一个内存块,导致True

【讨论】:

  • Python 将它在运行时使用的 all 对象存储在内存中,它不会将这些对象存储在其他任何地方,因此您的第一句话没有多大意义。 Python 也会愉快地创建多个具有相同值的 int 对象,只有 同一代码块中的文字会以这种方式缓存。
  • @MartijnPieters 这很有道理!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-19
  • 1970-01-01
  • 2013-10-02
  • 2020-10-08
  • 1970-01-01
相关资源
最近更新 更多