对象身份比较、is、整型对象和字符串对象的缓存
最近开始学习Python,其实知道Python和想学的念头算算也有两三年了(好惭愧><~),但怎么说也一直没有一个“诱因”吧。。然后实验室最近需要学习Swift对象存储,加之OpenStack这个开源云平台的整套东西都是用python写的,所以GO GO GO开始动手啦。
作为第一篇学习记录,题目实在是不好起。。进入正题。。
首先,抛出题目:
定义变量
1 a = 10 2 b = 10 3 c = 100 4 d = 100 5 e = 10.0 6 f = 10.0
请给出以下比较的输出结果
1 a is b 2 #True 3 4 c is d 5 #True 6 7 e is f 8 #False
首先,我们需要辨别is和==的区别:is用于测试两个对象是否指向同一个对象,而==比较的是对象的值。所以
a is b
这个表达式等价于线面这个表达式:
id(a) == id(b)
因此在上述题目中,我们创建的这“6个”数值对象,实际上并不是6个,而是a和b指向同一个,c和d指向同一个,e和f分别为一个值为10.0的对象。为什么我们本应创建的6个对象变成了4个呢?这是由于整型对象和字符串对象是不可变对象,所以python会很高效的缓存它们,这会造成我们认为python应该创建新对象时,它却没有创建新对象的假象。再来看两个例子:
x = 9999 y = 9999 s1 = 'a string' s2 = 'a string' # 输出结果 x is y #False s1 is s2 #True
x和y都创建了9999,为什么它们又没有指向同一个9999对象呢?这是因为python仅缓存简单整型,因为它认为在python应用程序中这些小整型会被经常用到,范围会根据版本不同有所变动。在Python2.3中决定,在预定义缓存字符串表之外的字符串,如果不再有任何引用指向它,那么这个字符串将不会被缓存。
此外,针对另一种不可变类型 元组,它的行为与整型对象和字符串对象有些不同,例如:
t1 = () t2 = () t3 = (1, 2) t4 = (1, 2) #输出结果 t1 is t2 #True t3 is t4 #False
因此,并不能说明不可变类型中相同的对象值具有相同的引用,要看具体的整型数值范围、元组是否为空等情况。