参考文献1:http://makaidong.com/maikerniuniu/1280_9073599.html

参考文献2:https://www.cnblogs.com/fandx/p/10462913.html

A. 变量的存储

[A.1] 概念:在高级语言中,变量是对内存及其地址的抽象。对于python而言,python的一切变量都是对象,变量的存储,采用了引用语义的方式,存储的只是一个变量的值所在的内存地址,而不是这个变量的只本身。

[A.2] 引用语义:在python中,变量保存的是对象(值)的引用,我们称为引用语义。采用这种方式,变量所需的存储空间大小一致,因为变量只是保存了一个引用。也被称为对象语义和指针语义。

[A.3]值语义:有些语言采用的不是这种方式,它们把变量的值直接保存在变量的存储区里,这种方式被我们称为值语义,例如C语言,采用这种存储方式,每一个变量在内存中所占的空间就要根据变量实际的大小而定,无法固定下来。

[A.4] 说明:由于python中的变量都是采用的引用语义,数据结构可以包含基础数据类型,导致了在python中每个变量中都存储了这个变量的地址,而不是值本身;对于复杂的数据结构来说,里面的存储的也只只是每个元素的地址而已.

B. 基础类型和数据结构类型变量重新赋值的存储变化:

[B.1] 数据类型重新初始化对python语义引用的影响

变量的每一次初始化,都开辟了一个新的空间,将新内容的地址赋值给变量。对于下图来说,我们重复的给str1赋值,其实在内存中的变化如下图:

从上图我们可以看出,str1在重复的初始化过程中,是因为str1中存储的元素地址由'hello world'的地址变成了'new hello world'的。

[B.2]数据结构内部元素变化重对python语义引用的影响

对于复杂的数据类型来说,改变其内部的值对于变量的影响:

当对列表中的元素进行一些增删改的操作的时候,是不会影响到lst1列表本身对于整个列表地址的,只会改变其内部元素的地址引用。可是当我们对于一个列表重新初始化(赋值)的时候,就给lst1这个变量重新赋予了一个地址,覆盖了原本列表的地址,这个时候,lst1列表的内存id就发生了改变。上面这个道理用在所有复杂的数据类型中都是一样的。

C. 变量赋值

[C.1]简单的str的赋值

我们刚刚已经知道,str1的再次初始化(赋值)会导致内存地址的改变,从上图的结果我们可以看出修改了str1之后,被赋值的str2从内存地址到值都没有受到影响。看内存中的变化,起始的赋值操作让str1和str2变量都存储了‘hello world’所在的地址,重新对str1初始化,使str1中存储的地址发生了改变,指向了新建的值,此时str2变量存储的内存地址并未改变,所以不受影响。

[C.2]复杂的数据结构中的赋值

刚刚我们看了简单数据类型的赋值,现在来看复杂数据结构变化对应内存的影响

上图对列表的增加修改操作,没有改变列表的内存地址,lst1和lst2都发生了变化。对照内存图我们不难看出,在列表中添加新值时,列表中又多存储了一个新元素的地址,而列表本身的地址没有变化,所以lst1和lst2的id均没有改变并且都被添加了一个新的元素。简单的比喻一下,我们出去吃饭,lst1和lst2就像是同桌吃饭的两个人,两个人公用一张桌子,只要桌子不变,桌子上的菜发生了变化两个人是共同感受的。

D. 浅拷贝和深拷贝的区别

[D.1]浅拷贝

浅拷贝:不管多么复杂的数据结构,浅拷贝都只会copy一层。下面就让我们看一张图,来了解一下浅浅拷贝的概念。

图1

图2

看上面两张图,图1表示的是一个列表sourcelist,sourcelist = ['str1','str2','str3','str4','str5',['str1','str2','str3','str4','str5']];

在图2在原有的基础上多出了一个浅拷贝的copylist,copylist = ['str1','str2','str3','str4','str5',['str1','str2','str3','str4','str5']];

sourcelist和copylist表面上看起来一模一样,但是实际上在内存中已经生成了一个新列表,copy了sourceLst,获得了一个新列表,存储了5个字符串和一个列表所在内存的地址。

我们看下面分别对两个列表进行的操作,红色的框框里面是变量初始化,初始化了上面的两个列表;我们可以分别对这两个列表进行操作,例如插入一个值,我们会发现什么呢?如下所示:

从上面的代码我们可以看出,对于sourceLst和copyLst列表添加一个元素,这两个列表好像是独立的一样都分别发生了变化,但是当我修改lst的时候,这两个列表都发生了变化,这是为什么呢?我们就来看一张内存中的变化图:

我们可以知道sourceLst和copyLst列表中都存储了一坨地址,当我们修改了sourceLst1的元素时,相当于用'sourceChange'的地址替换了原来'str1'的地址,所以sourceLst的第一个元素发生了变化。而copyLst还是存储了str1的地址,所以copyLst不会发生改变。

当sourceLst列表发生变化,copyLst中存储的lst内存地址没有改变,所以当lst发生改变的时候,sourceLst和copyLst两个列表就都发生了改变。

这种情况发生在字典套字典、列表套字典、字典套列表,列表套列表,以及各种复杂数据结构的嵌套中,所以当我们的数据类型很复杂的时候,用copy去进行浅拷贝就要非常小心。。。

[D.2] 深拷贝

深拷贝——即python的copy模块提供的另一个deepcopy方法。深拷贝会完全复制原变量相关的所有数据,在内存中生成一套完全一样的内容,在这个过程中我们对这两个变量中的一个进行任意修改都不会影响其他变量。下面我们就来试验一下。

看上面的执行结果,这一次我们不管是对直接对列表进行操作还是对列表内嵌套的其他数据结构操作,都不会产生拷贝的列表受影响的情况。我们再来看看这些变量在内存中的状况:

看了上面的内容,我们就知道了深拷贝的原理。其实深拷贝就是在内存中重新开辟一块空间,不管数据结构多么复杂,只要遇到可能发生改变的数据类型,就重新开辟一块内存空间把内容复制下来,直到最后一层,不再有复杂的数据类型,就保持其原引用。这样,不管数据结构多么的复杂,数据之间的修改都不会相互影响。这就是深拷贝~~~

[D.3] 结论

结论一:

不管深拷贝还是浅拷贝对不可变数据类型都是引用内存地址

不管深拷贝还是浅拷贝对可变数据类型都是会重新创建新的内存空间

结论二:

浅拷贝:

外层是不可变类型、不管内层是否可变都是引用拷贝

外层是可变类型,不管内层是否可变都会从新创建新的内存空间

深拷贝:

外层是不可变类型,会递归判断内层数据类型、如果可变则创建新的内存地址、都为不可变就是引用拷贝

外层是可变数据类型、不管内层是否可变都会创新新的内存地址、但是内部如果为可变则递归创建、不可变则为引用地址

总结之:

浅拷贝:

浅拷贝只做最顶层的数据类型判断

如果顶层是可变类型则创建新的内存空间

如果顶层是不可变数据类型就是引用拷贝

深拷贝:

深拷贝做递归拷贝,可以递归拷贝所有的内部嵌套数据(可以理解为循环遍历做浅拷贝判断)

深拷贝递归拷贝遇到可变类型则创建新的内存空间

深拷贝递归拷贝遇到不可变数据类型就是拷贝的引用

python保存变量_Python变量存储相关推荐

  1. python保存变量_python | 变量-保存与命名规则

    1 变量生成 python中生成变量无须事先声明,系统会根据赋值或表达式运算结果值,自动推断变量类型.在python中,变量生成的语法如下:变量名 = 数据或表达式 x = 123 type(x) # ...

  2. python保存数据型变量_Python基础学习笔记(一)变量与数据类型

    https://m.toutiao.com/is/J3fN6eK/ Python是一门易学的面向对象的程序设计语言,可以轻易地完成界面.文件.封装等高阶需求,可移植性好,有非常多功能强大的库与包,如N ...

  3. python的常量和变量_python变量和常量

    变量 什么是变量? 变量,是用于在内存中存放程序数据的容器 计算机的最核心功能就是"计算", 计算需要数据源,数据源要存在内存里,比如我要把小明的姓名.身高.年龄信息存下来,后面程 ...

  4. python怎么定义int变量_Python 变量类型 | 菜鸟教程

    Python 变量类型 变量存储在内存中的值.这就意味着在创建变量时会在内存中开辟一个空间. 基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中. 因此,变量可以指定不同的数据 ...

  5. python定义int变量_Python变量以及常用数字类型(上)

    好好学习,天天向上.又到了齐小猴写笔记的时间,今天的内容是python 变量以及常用数字类型,废话不多说,撸起袖子开始写 变量 1.说到变量,先回顾上一篇说过的标识符,自己定义,自己命名,由字母,下划 ...

  6. python函数名是变量_Python 变量做函数名的简单示例

    这篇文章主要为大家详细介绍了Python 变量做函数名的简单示例,具有一定的参考价值,可以用来参考一下. 对python这个高级语言感兴趣的小伙伴,下面一起跟随512笔记的小编两巴掌来看看吧! PHP ...

  7. python格式化输出多个变量_Python变量的格式化输出

    print() 函数使用以 % 开头的转换说明符对各种类型的数据进行格式化输出. 转换说明符(Conversion Specifier)只是一个占位符(也称为格式化操作符),它会被后面表达式(变量.常 ...

  8. torch 变量_python变量

    ⽬目标 变量量的作⽤用定义变量量认识数据类型 ⼀一. 变量量的作⽤用 举例例体验:我们去图书馆读书,怎么样快速找到⾃自⼰己想要的书籍呢?是不不是管理理员提前将书放到固定位置,并把这个位置进⾏行行了了编 ...

  9. python保存数据_Python 保存数据的方法(4种方法)

    Python 保存数据的方法: open函数保存 使用with open()新建对象 写入数据(这里使用的是爬取豆瓣读书中一本书的豆瓣短评作为例子) import requests from lxml ...

最新文章

  1. 2021年春季学期-信号与系统-第九次作业参考答案-第二小题
  2. android 分辨率显示不全,安卓手机分辨率太高软件显示不全?任意软件全屏运行详细教程...
  3. 前端学习(499):水平居中布局得第一种方式得优点和缺点
  4. vmware 搭建k8s无法ping通子节点_一波四折 —— 记一次K8S集群应用故障排查
  5. 史上最快! 10小时大数据入门(一)-大数据概述
  6. Stack Overflow: The Architecture - 2016 Edition(Translation)
  7. javascript 近乎神话般的概念:闭包
  8. window直接运行不需要环境的软件是什么语言开发的_C语言为何不会过时?你需要掌握多少种语言?_C 语言...
  9. 坐标字符NYOJ 298 点的变换 (矩阵快速幂)
  10. 数字证书驱动_网上申报中环CA数字证书更新流程(图解)
  11. WebRAY网站检查技术支撑平台的实践
  12. mysql数据库银行项目题_银行数据库笔试编程题
  13. 【2022西电A测】温度检测控制仿真系统
  14. 2020年重磅喜讯!热烈祝贺王家林大咖大数据经典传奇著作《Spark大数据商业实战三部曲》 畅销书籍第二版 清华大学出版社发行上市! 前浪致 Spark + AI 后浪
  15. linux下的文件系统,Linux系统中常见的文件系统有哪些?
  16. Delphi隐藏/显示Windows桌面上的图标
  17. MPP架构是什么?看这一篇就行了。。
  18. [CTF]Rabbit加密
  19. 360集团2016JAVA研发工程师内推笔试题
  20. WINDOWS10 启动失败 你的电脑/设备需要修复

热门文章

  1. SpringBoot 2 整合 Spring Session 最简操作
  2. C#详解值类型和引用类型区别
  3. Received status code 403 from server: Forbidden
  4. RNN-GRU-LSTM变体详解
  5. iOS开发——基础篇——iOS开发 Xcode8中遇到的问题及改动
  6. 第三周作业(三)WordCount
  7. DevexPress checkedit 多选解决方案(原创)
  8. 如何不用MDI方式在Form1上显示Form2
  9. mysql库与oracle库的区别_开源数据库Oracle与MySQL的SQL语法区别
  10. Python自定义类的成员并不一直是所有对象共享的