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
),ID140524904
。一旦你做了b+=1
,你就有了2
,它位于别处。a
和b
都引用了内存中的同一个对象(1
),ID140524904
。一旦你做了b+=1
,你就有了2
,它位于别处
在python中,所有变量都是指向某些对象的指针。偶数
数字是不可变的对象。因此,CPython不需要创建具有相同值的新对象
这并不意味着CPython将始终使用相同的对象
在第一个示例中,变量a
和b
指向同一个对象
当makeb+=1
时,您“创建”了新对象2
在python中,所有变量都是指向某些对象的指针。偶数
数字是不可变的对象。因此,CPython不需要创建具有相同值的新对象
这并不意味着CPython将始终使用相同的对象
在第一个示例中,变量a
和b
指向同一个对象
当makeb+=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