参考资料:https://blog.csdn.net/answer3lin/article/details/86430074
一、python中数据类型分类思维导图
二、值得注意的是:
1、Python中的变量都是指针,因此是没有类型限制的,且指针的内存空间大小是与类型无关的,其内存空间只是保存了所指向数据的内存地址。
2、值类型是不可变的(immutable),这种不可变是指该值类型的变量指向的空间所存储的地址是不变的,而非内容不变,例如我们可以有以下操作:
tupleA = (1,2,[3,4,5])
tupleA[2][1] = 7
print(tupleA)
运行结果为:(1,2,[3,7,5])
但是如下操作是不正确的
tupleA = (1,2,[3,4,5])
tupleA[0] = 7
print(tupleA)
这是因为1与2为int类型,为值类型,一旦值发生改变,其地址也将改变,而tuple内成员的地址是不允许修改的;但是[3,4,5]为list类型,为引用类型,是可以改变的,当其值发生改变不会改变地址值,如一个列表经过append,pop等操作时其地址是不会发生改变的,读者可以使用id()方法测试。
第二点小总结:不可变对象的“值"(由上知“值”为地址)不能改变,但它的组成对象是能做到改变的。
3、Python在底层做了一定的优化,对于使用过小整数以及短字符串都会被缓存起来,这样子有什么好处呢?请看下面的例子:
对值类型而言,当我们执行形如x = 1等操作时,会开辟一个空间存放1,此时不妨执行id(x)和id(1),我们会发现两者相同,再执行y = 1 id(y) ,则仍有id(y) = id(x) = id(1),此时指针x与y皆指向1,也就是说,只要值相同,地址也将相同,这无疑减少了不少内存空间的使用。
4、Python中的参数传递都是传递引用,也就是传递的是内存地址。只不过对于不可变类型,传递引用和传递值没什么区别。而对于可变类型,传递引用是真的传递内存的地址。
听说python只允许引用传递是为方便内存管理,因为python使用的内存回收机制是计数器回收,就是每块内存上有一个计数器,表示当前有多少个对象指向该内存。每当一个变量不再使用时,就让该计数器-1,有新对象指向该内存时就让计数器+1,当计时器为0时,就可以收回这块内存了。当然还有其他的GC方法,否则计数器回收,无法解决循环引用的问题。