首先,我们需要知道在python中哪些是可变数据类型,哪些是不可变数据类型。可变数据类型:列表list和字典dict;不可变数据类型:整型int、浮点型float、字符串型string和元组tuple。

用一句话来概括上述过程就是:“python中的不可变数据类型,不允许变量的值发生变化,如果改变了变量的值,相当于是新建了一个对象,而对于相同的值的对象,在内存中则只有一个对象,内部会有一个引用计数来记录有多少个变量引用这个对象;可变数据类型,允许变量的值发生变化,即如果对变量进行append、+=等这种操作后,只是改变了变量的值,而不会新建一个对象,变量引用的对象的地址也不会变化,不过对于相同的值的不同对象,在内存中则会存在不同的对象,即每个对象都有自己的地址,相当于内存中对于同值的对象保存了多份,这里不存在引用计数,是实实在在的对象。

初学python的时候,可能会有很多疑惑,尤其是最先接触的所谓的“可变数据类型”和“不可变数据类型”。python与C/C++不一样,它的变量使用有自己的特点,当初学python的时候,一定要记住“一切皆为对象,一切皆为对象的引用”这句话,其实这个特点类似于JAVA,所以在python里面大家也不用担心类似于C/C++中的指针的复杂问题。下面本文将对python里面的“可变数据类型”和“不可变数据类型”进行分析。

首先,我们需要知道在python中哪些是可变数据类型,哪些是不可变数据类型。可变数据类型:列表list和字典dict;不可变数据类型:整型int、浮点型float、字符串型string和元组tuple。

然后,我们以int和list为例,来看看“可变数据类型”和“不可变数据类型”到底有什么区别。

(1)不可变数据类型分析。先来看一段程序:

>>> x = 1

>>> id(x)

31106520

>>> y = 1

>>> id(y)

31106520

>>> x = 2

>>> id(x)

31106508

>>> y = 2

>>> id(y)

31106508

>>> z = y

>>> id(z)

31106508

>>> x += 2

>>> id(x)

31106484

上面这段程序都是对不可变数据类型中的int类型的操作,id()查看的是当前变量的地址值。我们先来看x = 1和y = 1两个操作的结果,从上面的输出可以看到x和y在此时的地址值是一样的,也就是说x和y其实是引用了同一个对象,即1,也就是说内存中对于1只占用了一个地址,而不管有多少个引用指向了它,都只有一个地址值,只是有一个引用计数会记录指向这个地址的引用到底有几个而已。当我们进行x = 2赋值时,发现x的地址值变了,虽然还是x这个引用,但是其地址值却变化了,后面的y = 2以及z = y,使得x、y和z都引用了同一个对象,即2,所以地址值都是一样的。当x和y都被赋值2后,1这个对象已经没有引用指向它了,所以1这个对象占用的内存,即31106520地址要被“垃圾回收”,即1这个对象在内存中已经不存在了。最后,x进行了加2的操作,所以创建了新的对象4,x引用了这个新的对象,而不再引用2这个对象。

那么为什么称之为不可变数据类型呢?这里的不可变大家可以理解为x引用的地址处的值是不能被改变的,也就是31106520地址处的值在没被垃圾回收之前一直都是1,不能改变,如果要把x赋值为2,那么只能将x引用的地址从31106520变为31106508,相当于x = 2这个赋值又创建了一个对象,即2这个对象,然后x、y、z都引用了这个对象,所以int这个数据类型是不可变的,如果想对int类型的变量再次赋值,在内存中相当于又创建了一个新的对象,而不再是之前的对象。从下图中就可以看到上面程序的过程。

图1 python不可变数据类型分析

从上面的过程可以看出,不可变数据类型的优点就是内存中不管有多少个引用,相同的对象只占用了一块内存,但是它的缺点就是当需要对变量进行运算从而改变变量引用的对象的值时,由于是不可变的数据类型,所以必须创建新的对象,这样就会使得一次次的改变创建了一个个新的对象,不过不再使用的内存会被垃圾回收器回收。

(2)可变数据类型分析。下面同样先看一段程序。

>>> a = [1, 2, 3]

>>> id(a)

41568816

>>> a = [1, 2, 3]

>>> id(a)

41575088

>>> a.append(4)

>>> id(a)

41575088

>>> a += [2]

>>> id(a)

41575088

>>> a

[1, 2, 3, 4, 2]

从上面的程序中可以看出,进行两次a = [1, 2, 3]操作,两次a引用的地址值是不同的,也就是说其实创建了两个不同的对象,这一点明显不同于不可变数据类型,所以对于可变数据类型来说,具有同样值的对象是不同的对象,即在内存中保存了多个同样值的对象,地址值不同。接着来看后面的操作,我们对列表进行添加操作,分别a.append(4)和a += [2],发现这两个操作使得a引用的对象值变成了上面的最终结果,但是a引用的地址依旧是41575088,也就是说对a进行的操作不会改变a引用的地址值,只是在地址后面又扩充了新的地址,改变了地址里面存放的值,所以可变数据类型的意思就是说对一个变量进行操作时,其值是可变的,值的变化并不会引起新建对象,即地址是不会变的,只是地址中的内容变化了或者地址得到了扩充。下图对这一过程进行了图示,可以很清晰地看到这一过程。

图2 python可变数据类型分析

从上述过程可以看到,可变数据类型是允许同一对象的内容,即值可以变化,但是地址是不会变化的。但是需要注意一点,对可变数据类型的操作不能是直接进行新的赋值操作,比如说a = [1, 2, 3, 4, 5, 6, 7],这样的操作就不是改变值了,而是新建了一个新的对象,这里的可变只是对于类似于append、+=等这种操作。

总之,用一句话来概括上述过程就是:“python中的不可变数据类型,不允许变量的值发生变化,如果改变了变量的值,相当于是新建了一个对象,而对于相同的值的对象,在内存中则只有一个对象,内部会有一个引用计数来记录有多少个变量引用这个对象;可变数据类型,允许变量的值发生变化,即如果对变量进行append、+=等这种操作后,只是改变了变量的值,而不会新建一个对象,变量引用的对象的地址也不会变化,不过对于相同的值的不同对象,在内存中则会存在不同的对象,即每个对象都有自己的地址,相当于内存中对于同值的对象保存了多份,这里不存在引用计数,是实实在在的对象。”

最后,大家主要区分开什么是变量值的变化、什么是变量引用的对象地址的变化这些概念就很清楚了,千说万说都不如自己动手写一些程序测试一下看看来得实在,所以建议大家有什么疑惑可以自己写一些基本的程序测试一下便知道结果。如果大家有新的意见,欢迎补充,谢谢。

python中变量类型在程序中可以改变_python的可变与不可变数据类型相关推荐

  1. python中变量类型在程序中可以改变_Python中的变量和数据类型,python,及

    变量 变量的定义: 在程序中,有时我们需要对2个数据进行求和,那么该怎样做呢? 大家类比一下现实生活中,比如去超市买东西,往往咱们需要一个菜篮子,用来进行存储物品,等到所有的物品都购买完成后,在收银台 ...

  2. python中变量类型在程序中可以改变_详细解析Python当中的数据类型和变量

    数据类型 计算机顾名思义就是可以做数学计算的机器,因此,计算机程序理所当然地可以处理各种数值.但是,计算机能处理的远不止数值,还可以处理文本.图形.音频.视频.网页等各种各样的数据,不同的数据,需要定 ...

  3. 关于python的元组类型以下选项中描述错误的是_关于Python的元组类型,以下选项中描述错误的是【】...

    [单选题]给出如下代码: fname=imput('请输入要打开的文件:') fi=open(fname,'r') for line in fi.readlines(): print(line) fi ...

  4. 关于python浮点数类型错误的是_关于Python的数字类型,以下选项中描述错误的是...

    [单选题]以下程序的输出结果是: lcat =["狮子","猎豹","虎猫","花豹","孟加拉虎" ...

  5. python中复数类型与数学中复数的概念一致_2020年9月计算机二级python选择题在线题库12/15...

    1.在最坏情况下比较次数相同的是(). A.冒泡排序与快速排序 B.简单插入排序与希尔排序 C.简单选择排序与堆排序 D.快速排序与希尔排序 A  [解析]冒泡排序.快速排序.简单插入排序.简单选择排 ...

  6. python的复数类型表示数学中的复数对吗_关于Python的复数类型,以下选项中描述错误的是...

    [单选题]下面代码的输出结果是 >>> x = "Happy Birthday to you!" >>> x * 3 [判断题]打开一个文本文件 ...

  7. C51中变量类型和范围

    文章目录 1 C51中变量类型和范围 1 C51中变量类型和范围 C51中变量类型和范围需要特别注意下,int只占两个字节,指针类型也是占2个字节. 参考资料: 手把手教你学51单片机:C语言版

  8. python如何在网络爬虫程序中使用多线程(threading.Thread)

    python如何在网络爬虫程序中使用多线程 一.多线程的基础知识 二.在网络爬虫中使用多线程 2.1 从单线程版本入手 2.2 将单线程版本改写为多线程版本 2.3 运行多线程版本程序 2.4 将多线 ...

  9. python查看数据类型的方法_pycharm下查看python的变量类型和变量内容的方法

    pycharm下查看python的变量类型和变量内容的方法 用过Matlab的同学基本都知道,程序里面的变量内容可以很方便的查看到,但python确没这么方便,对于做数据处理的很不方便,其实不是没有这 ...

最新文章

  1. pat 多项式A/B
  2. 量子计算机就要来了,它真的能改变世界吗?
  3. 微软日本每周只上四天班,销售额提升39.9%!网友:老板快来看啊
  4. 免疫算法(二进制)算例(源码实现)
  5. 【已解决】Exception in thread “main“ java.lang.NullPointerException
  6. 01-MyBatis入门程序
  7. 李开复:听AI大佬吐槽真实的人工智能
  8. python2 python3 通信_python与USB通信
  9. 大前端的自动化工厂(2)—— SB Family
  10. java遍历嵌套二维map输出下标_Map集合嵌套 4种遍历方式
  11. idea 初始界面_IDEA 初始配置教程
  12. 关于python循环
  13. std::string.assign()的用法-爱情滕-搜狐博客
  14. docker - 常用命令详解
  15. 将AD原理图文件和PCB文件转换为KiCad格式的方法
  16. Unicode 中文,日文,西欧语言Unicode编码域(区间)
  17. 【iOS】file not found: .../Build/Products/Debug-iphonesimulator file not found
  18. pywifi破解密码
  19. dataframe如何定义列名称
  20. Unity如何实现VR漫游

热门文章

  1. vuejs和webpack项目(VueComponent)初尝试——瀑布流组件
  2. Aspx页面生命周期(转)
  3. 和平精英清明节服务器维修时间,和平精英体验服关服维护要多久 和平精英体验服什么时候开放...
  4. oracle分组聚合查询,Oracle中分组查询group by用法规则解析
  5. 微信sdk服务器支付文档,微信支付-普通下单开发者文档
  6. 计算机课程设计红绿灯,武汉大学电气工程学院计算机课程设计1:红绿灯
  7. JDK1.8中的HashMap,HashTable,ConcurrentHashMap有什么区别?
  8. centos打显卡驱动命令_CentOS7显卡驱动问题
  9. 编写时钟aplet程序java,编写时钟 Applet 程序
  10. dalsa线扫相机调试文档_线阵相机调试文档