1

重複の可能性:
Pythonの「is」演算子は整数で予期しない動作をします
なぜ(0-6)は-6 = Falseですか?

だから、(python 2.6.5)で少し遊んでいるとid、次のことに気づきました(シェルセッション):

>>> a = 1
>>> id(a)
140524904
>>> b = 1
>>> id(b)
140524904

もちろん、変数の1つを変更するとすぐに、新しいメモリアドレスに割り当てられます。

>>> b += 1
>>> id(b)
140524892

同じ値を持つ両方の変数を同じメモリ位置に最初に割り当てるのは通常の動作ですか、それともCPythonの最適化だけですか?

追伸私はでコードを閲覧するのに少し時間を費やしましたparserが、変数がどこにどのように割り当てられているかを見つけることができませんでした。

4

4 に答える 4

3

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になる理由を説明しています。この配列に収まる値を持つように数値が計算されるときはいつでも、結果のオブジェクトは代わりにこの配列から単純に選択され、メモリを少し節約します。Truea += 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_intsObjects/longobject.c

-編集-私は、いくつかのリテラルのインターンについて同様の答えがあることにelssarが指摘したのを見ます。この事実は、この回答で言及されているように、のドキュメントにも記載されています。PyInt_FromLong

于 2012-12-20T17:00:44.063 に答える
2
  1. Pythonでは、すべての変数はいくつかのオブジェクトへのポインターです。偶数。
  2. 番号は不変オブジェクトです。したがって、CPythonは同じ値で新しいオブジェクトを作成する必要はありません。
  3. これは、CPythonが常に同じオブジェクトを使用することを意味するものではありません。
  4. 最初の例では、変数ab同じオブジェクトを指しています。
  5. b += 1新しいオブジェクトを「作成」するとき2
于 2012-12-20T15:52:09.343 に答える
2

ここで、「変数」という用語は正確にする必要があります。一方にはオブジェクトがあり、もう一方にはオブジェクトにバインドされている名前があります。

を実行すると、とはa = b = 1両方とも、を表す同じオブジェクトにバインドされます。ab1

もしそうならa = 1; b = 1、それが同じであるのはCPythonの詳細だと思います。一般に、実装では、ここで両方を表し、両方を使用する2つのオブジェクトを選択できます1。しかし、それはメモリの浪費になるので、一般的にこの方法では行われません。

于 2012-12-20T15:53:26.027 に答える
1

a両方とも、IDが付いたbメモリ()内の同じオブジェクトを参照します。一度あなたが持っている、それは他の場所にあります。1140524904b += 12

于 2012-12-20T15:51:55.890 に答える