python的数据类型相关知识(持续累积)
一. python的数据类型分类
二. is 和 ==的关系
is 判断是两个对象的存储地址是否一样,即比较两者是否是一个实例对象,是否指向同一个内存地址,即判断 id(a)==id(b)。而 == 判断的是两个对象的内容时候相等,默认会调用对象的__eq__()方法。
1. int
出于对性能的考虑,对于整数对象,python把一些频繁使用的整数对象缓存起来,保存到small_ints 里,在python的整个生命周期中,任何需要引用这些整数对象的地方,都不需要重新创建新的对象,而实直接引用缓存中的对象。这个小对象池的范围是[-5,256],一旦超过这个范围,在python中就以两个对立的对象出现。
除此以外,python出于对性能的考虑,但凡是不可变对象,在同一个代码块中的对象。只要是值相同的对象,就不会重复创建,而是直接应用已经存在的对象。(这里对于代码块的含义有待商榷)
2. float
float类型可以认为每个赋值都是创建一个对象,因为float有点多,所以没必要和int一样了
3. string
string对象也是不可变对象,python有个intern机制,简单说就是维护一个字典,这个字典维护已经创建字符串(key)和它的字符串对象的地址(value),每次创建字符串对象都会和这个字典比较,没有就创建,重复了就用指针进行引用就可以了。
string实现了intern共享?我觉得是一种空间效率和时间效率的妥协。相比于数字,string本身参与的运算要少很多,而且string本身占据的空间也大许多,因此string的主要问题在于不共享带来的空间浪费,所以string实现了很费时间的intern操作。对于数字情况正好相反。作为一个数字,需要做的运算要比string多太多了,而且大小比string也小很多。
但是有一些特殊的情况,我暂时不不知道原因。比如:
- 字符串中使用 * 表示连续一样的字符时,不能超过20个,否则id不同。
- 不能包含特殊字符,否则id不同。
4. tuple
tuple它是不可变对象,理应和int和string一样会做一个缓存,但是书上没有说明,于是看了看源码,发现tuple的数据结构很简单,简单到不能再简单,就是一个数组,里面是元组的迭代对象,这个对象指向的是各个元素.最关键的是元组没有实现intern机制!所以元组虽然是不可变对象,但它同时也是一个数组,这个数组和c里的数组一样,每次创建都会分配内存空间。
三. hash和数据类型的关系
不可变数据类型有hash函数,而不可变数据类型没有hash函数。因为hash是利用对象值进行hash的,不过是可变数据类型的话,就会出现桶错误。比如使用可变数据类型进行了键值对的存储后,修改了可变数据类型的值之后,再次使用hash函数映射就不能复现 之前的存储线路了。