偶尔手贱敲了下交互命令
>>> a = 10
>>> b = 10
>>> a is b
True
>>> a = 1000
>>> b = 1000
>>> a is b
False
>>>
突然有点奇怪了,这可是不可变类型,尽管值一致,但是创建的应该是不同的对象,为什么会出现True呢,于是写一个弱小的code测试一下:
#!/usr/bin/env python
a = 10
b = 10
while True:
if a is not b:
break
else:
a += 1
b += 1
print a
运行结果是257,也就是上限256,产生了一种本来认为应该创建新对象,它却没有创建新对象的假象,这是因为如此小整型会经常用到,会被缓存起来,貌似为了提高效率,python2.7整型缓存的范围是[-5, 256],不仅仅是整型,字符串也是类似
python的源码,intobject.c,可以看到大概这些内容:
#define NSMALLPOSINTS 257
#define NSMALLNEGINTS 5
/* References to small integers are saved in this array so that they
can be shared.
The integers that are saved are those in the range
-NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive).
*/
static PyIntObject *small_ints[NSMALLNEGINTS + NSMALLPOSINTS];
PyObject *
PyInt_FromLong(long ival)
{
register PyIntObject *v;
//如果 -5 <= ival && ival < 257, 命中缓存~
if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) {
v = small_ints[ival + NSMALLNEGINTS];
Py_INCREF(v);
return (PyObject *) v;
}
if (free_list == NULL) { //这个是另一个优化,相当于内存池,用链表实现
if ((free_list = fill_free_list()) == NULL)
return NULL;
}
/* Inline PyObject_New */
v = free_list;
free_list = (PyIntObject *)Py_TYPE(v);
PyObject_INIT(v, &PyInt_Type);
v->ob_ival = ival;
return (PyObject *) v;
}
python里一切皆对象,一切传递都是传递引用
一个数字对象被创建赋给a,另一个数字对象被创建赋给b,尽管两个对象保存的是同样大小的值,但实际上系统中保存的都是两个独立的对象,其中a是第一个对象的引用,b是第二个对象的引用,这里是两个不同的对象,尽管这两个对象有同样大小的数值
对象就好像一个装着内容的盒子,当一个对象被赋值到一个变量,就像是在这个盒子上贴了一个标签,表示创建了一个引用,每当这个对象有了一个新的引用,就会在盒子上新贴一张标签,当一个引用被销毁时,这个标签就会被撕掉,当所有标签都被撕掉,这个盒子就会被回收