glglglで述べたように、これはCPythonの実装の詳細です。CPythonのソースコード(バージョン3.3.0など)を見るとObjects/longobject.c
、何が起こっているのかに対する答えが見つかります。
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
/* Small integers are preallocated in this array so that they
can be shared.
The integers that are preallocated are those in the range
-NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive).
*/
static PyLongObject small_ints[NSMALLNEGINTS + NSMALLPOSINTS];
これは、あなたが言ったとしても、後a = 1; b = 1
に、a is b
になる理由を説明しています。この配列に収まる値を持つように数値が計算されるときはいつでも、結果のオブジェクトは代わりにこの配列から単純に選択され、メモリを少し節約します。True
a += 2; b +=2; a -= 2; b -= 2
small_ints
次のような関数を使用して、この配列の境界を把握できます。
def binary_search(predicate, lo, hi):
while lo + 1 < hi:
mid = (lo + hi) / 2
if predicate(mid):
lo = mid
else:
hi = mid
return lo
def is_small_int(n):
p = n + 1
q = n + 1
return (p - 1) is (q - 1)
def min_neg_small_int():
p, q = -1, -1
if p is not q:
return 0
while p is q:
p += p
q += q
return binary_search(is_small_int, p / 2, p) - 1
def max_pos_small_int():
p, q = 1, 1
if p is not q:
return 0
while p is q:
p += p
q += q
return binary_search(is_small_int, p / 2, p)
def small_int_bounds():
return (min_neg_small_int(), max_pos_small_int())
私のビルド(Python 2.7、64ビットWindowsビルド)の場合、small_int_bounds() == (-5, 256)
。これは、との間の数値が-5
の配列を256
介して共有されることを意味します。small_ints
Objects/longobject.c
-編集-私は、いくつかのリテラルのインターンについて同様の答えがあることにelssarが指摘したのを見ます。この事実は、この回答で言及されているように、のドキュメントにも記載されています。PyInt_FromLong