Это связано с простой оптимизацией на этапе компиляции байт-кода; если одна и та же константа появляется в одном и том же коде более одного раза, она создается только один раз, и каждое использование константы будет относиться к одному и тому же экземпляру.
Мы можем исследовать байт-код с помощью dis module:
>>> import dis
>>> dis.dis('l = 40000\nm=40000')
1 0 LOAD_CONST 0 (40000)
2 STORE_NAME 0 (l)
2 4 LOAD_CONST 0 (40000)
6 STORE_NAME 1 (m)
8 LOAD_CONST 1 (None)
10 RETURN_VALUE
>>> dis.dis('l = 40000\nm=40001')
1 0 LOAD_CONST 0 (40000)
2 STORE_NAME 0 (l)
2 4 LOAD_CONST 1 (40001)
6 STORE_NAME 1 (m)
8 LOAD_CONST 2 (None)
10 RETURN_VALUE
Обратите внимание, что в первом случае, когда обе константы равны 40000
, обе операции LOAD_CONST
загружают константу # 0, но во втором случае 40000
является константой. # 0 и 40001
являются константами # 1.
Кроме того, вы обычно получите разные результаты, если сделаете это в отдельных строках REPL, поскольку каждая строка в REPL компилируется и выполняется как отдельный код. объект, поэтому они не могут совместно использовать константы:
>>> l = 50000
>>> m = 50000
>>> id(l)
140545755966480
>>> id(m)
140545755966448
Но если вы сделаете оба в одной строке в REPL, тот же экземпляр константы будет снова использован, потому что это всего лишь одна строка, скомпилированная в один объект кода, поэтому константа может использоваться совместно:
>>> p = 60000; q = 60000
>>> id(p)
140545755966576
>>> id(q)
140545755966576