Python变量分配和'id'关键字

Python变量分配和'id'关键字,python,parsing,variables,Python,Parsing,Variables,可能重复: 因此,在使用id(python 2.6.5)时,我注意到以下内容(shell会话): 当然,只要我修改其中一个变量,它就会被分配到一个新的内存地址,即 >>> b += 1 >>> id(b) 140524892 最初将两个具有相同值的变量分配到同一内存位置是正常行为,还是仅仅是对CPython进行优化 另外,我花了一点时间浏览了解析器中的代码,但找不到变量分配的位置和方式。a和b都引用了内存中相同的对象(1),ID140524904。一旦你

可能重复:

因此,在使用
id
(python 2.6.5)时,我注意到以下内容(shell会话):

当然,只要我修改其中一个变量,它就会被分配到一个新的内存地址,即

>>> b += 1
>>> id(b)
140524892
最初将两个具有相同值的变量分配到同一内存位置是正常行为,还是仅仅是对CPython进行优化


另外,我花了一点时间浏览了
解析器中的代码,但找不到变量分配的位置和方式。

a
b
都引用了内存中相同的对象(
1
),ID
140524904
。一旦你做了
b+=1
,你就有了
2
,它位于别处。

a
b
都引用了内存中的同一个对象(
1
),ID
140524904
。一旦你做了
b+=1
,你就有了
2
,它位于别处

  • 在python中,所有变量都是指向某些对象的指针。偶数
  • 数字是不可变的对象。因此,CPython不需要创建具有相同值的新对象
  • 这并不意味着CPython将始终使用相同的对象
  • 在第一个示例中,变量
    a
    b
    指向同一个对象
  • 当make
    b+=1
    时,您“创建”了新对象
    2
  • 在python中,所有变量都是指向某些对象的指针。偶数
  • 数字是不可变的对象。因此,CPython不需要创建具有相同值的新对象
  • 这并不意味着CPython将始终使用相同的对象
  • 在第一个示例中,变量
    a
    b
    指向同一个对象
  • 当make
    b+=1
    时,您“创建”了新对象
    2
  • 这里的术语“变量”必须精确:一方面是对象,另一方面是绑定到对象的名称

    如果执行
    a=b=1
    ,则
    a
    b
    都绑定到表示
    1
    的同一对象

    如果你做
    a=1;b=1
    ,我认为这是一个相同的CPython细节。通常,一个实现可以选择有两个对象,这两个对象都表示
    1
    ,并且在这里都使用它们。但由于这会浪费内存,因此通常不会这样做。

    这里的术语“变量”必须精确:一方面是对象,另一方面是绑定到对象的名称

    如果执行
    a=b=1
    ,则
    a
    b
    都绑定到表示
    1
    的同一对象

    如果你做
    a=1;b=1
    ,我认为这是一个相同的CPython细节。通常,一个实现可以选择有两个对象,这两个对象都表示
    1
    ,并且在这里都使用它们。但是,由于这会浪费内存,所以通常不会以这种方式完成。

    这是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是b
    将是
    真的
    ,即使你说
    a+=2;b+=2;a-=2;b-=2
    。每当计算一个数字以使其具有适合此数组的值时,只需从该数组中拾取结果对象,即可节省一点内存

    您可以使用如下函数计算出这个
    小整数
    数组的边界:

    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())
    
    def二进制搜索(谓词、lo、hi):
    当lo+1
    对于我的构建(Python2.7,64位Windows构建),
    small\u int\u bounds()==(-5256)
    。这意味着
    -5
    256
    (含)之间的数字通过
    对象/longobject.c
    中的
    小整数
    数组共享

    -编辑-我看到有一个。正如。

    所述,这也是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是b
    将是
    真的
    ,即使你说
    a+=2;b+=2;a-=2;b-=2
    。每当计算一个数字以使其具有适合此数组的值时,只需从该数组中拾取结果对象,即可节省一点内存

    您可以使用如下函数计算出这个
    小整数
    数组的边界:

    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())
    
    def二进制搜索(谓词、lo、hi):
    当lo+1