python,可变对象,不可变对象,深拷贝,浅拷贝。
学习整理,若有问题,欢迎指正。
python 可变对象,不可变对象
- 可变对象
该对象所指定的内存地址上面的值可以被改变,变量被改变后,其所指向的内存地址上面的值,直接被改变,没有发生复制行为,也没有发生开辟新的内存地址行为。
python可变对象有,列表,字典,set集合
列如:

a = ['1','2','3'] print(id(a))
2275736586376 a.append('1') print(a)
['1', '2', '3', '1'] print(id(a))
2275736586376

我们可以看到,在向 a 列表内追加数据的时候,列表 a 前后的id没有发生变化,所以内存地址内,没有开辟新的空间,而是直接在原指定内存地址上面修改的。
图解:

2. 不可变对象
该对象所指定内存中的值不可以被改变,在改变某个对象的值的时候,由于其内存中的值不可以被改变,所以,会把原来的值复制一份再进行改变,这样就会计算机会开辟
一段新的内存空间来存储新的值,python 不可变对象有 int str float number,tuple,None
例如:

c = 'Hello' print(id(c))
2237718097848 print(c)
Hello c = c + 'World' print(id(c))
2237720838960 print(c)
HelloWorld

我们可以看到,c变量在追加的时候,两个id是不一样的,所以内存地址会发生变化,此变化为,将c变量所指向的内存,复制一份,然后再做更改。
图解:

此时,c的内存是指向 HelloWorld的,若Hello内存,长时间没有变量指定,则垃圾回收机制会自动回收的。
3. 等于赋值,并不会产生独立的对象单独存在,而是给原来的数据块打上一个新的标签,其中一个标签值被改变的时候,另一个标签也随之改变。

alist = [1,2,3,['a','b','c']]
b = alist
#此处id相同,所以指向同以内存地址
print(id(alist))
2030874445768
print(id(b))
2030874445768
#向alist内追加元素
alist.append(5)
print(alist)
[1, 2, 3, ['a', 'b', 'c'], 5]
print(b)
[1, 2, 3, ['a', 'b', 'c'], 5]
#向alist内的列表追加元素
alist[3].append("d")
print(alist)
[1, 2, 3, ['a', 'b', 'c', 'd'], 5]
print(b)
[1, 2, 3, ['a', 'b', 'c', 'd'], 5]
print(id(alist))
2030874445768
print(id(b))
2030874445768

由上面代码看出,alist所指向 [1,2,3,['a','b','c']] 内存地址,b 也是指定的[1,2,3,['a','b','c']]内存地址(id相同),所以a.append(5)后,alist变化,b也变化
图解:

由上图可以看出,无论alist做什么操作,b的内存地址都是指向alist的,所以alist的任何变化,b都会跟着变化。
4. 浅复制,浅复制分为两种情况
- 第一种情况,浅复制的值是不可变对象(数值,字符串,元组)时,与等值复制的是一样的,对象的id值与浅复制对象的id是一样的。

import copy a = 'abcde'
b = a
print(id(a))
2030878234584
print(id(b))
2030878234584 c = copy.copy(a)
print(id(c))
2030878234584 #当改变a的值
a = a + 'fg'
print(id(a))
2030878515304
#由于字符串为不可变对象,所以id(a)会发生变化,但是b,c不会发生变化,还是指向原有内存
print(id(b))
2030878234584
print(id(c))
2030878234584

由上面代码可以看出 b = a 其实b,a是指向同一块内存的(id)相同,c=copy.copy(a)也是和a,b指向同一块内存的(id相同),当a发生变化的时候,a会复制原有值,开辟一块新的内存
出来,此时,c与b还是指向原有内存(观察id)
图解:

- 当浅复制的值是可变对象(列表和元组)时会产生一个“不是那么独立的对象”存在。有两种情况:
- 复制的 对象中无 复杂 子对象,原来值的改变并不会影响浅复制的值,同时浅复制的值改变也并不会影响原来的值。原来值的id值与浅复制原来的值不同。
当浅复制的值是可变对象(列表,字典)时,改变的值不是 复杂子对象 代码如下:

list1 = ['1','2','3']
print(id(list1))
2030878577608 list2 = list1
print(id(list2))
2030878577608 list3 = list1.copy()
print(id(list2))
2030878577608
#上面三者id都一致 #然后在list1后面append一个新的元素,查看变化情况
list1.append('4')
print(list1)
['1', '2', '3', '4', '4']
print(id(list1))
2030878577608
print(list2)
['1', '2', '3', '4', '4']
print(id(list2))
2030878577608
print(list3)
['1', '2', '3']
print(id(list3))
2030878531400
#list3的值与list1,list2的值,不一样,且id也不一样了

当list2 = list1 的时候,完全指向同一块内存空间,list3 = list1.copy()的时候,list3也指向同一块内存空间,当list1发生变化的时候,list2与list1开辟出一块新的空间用来改变,list3还指向原有空间(或者相反)
图解:

- 当浅复制的值是可变对象(列表,字典)时,改变的值是 复杂子对象 代码如下:

l1 = [1,2,['a','b']]
l2 = l1
l3 = copy.copy(l2)
l4 = copy.deepcopy(l3)
print(id(l1))
2030878621960
print(id(l2))
2030878621960
print(id(l3))
2030878622664
print(id(l4))
2030878622728
#id可以看出,l1,l2的id没有改变,但是,l3,l4的id发生了变化
l1[2].append('a')
print(id(l1))
2030878621960
print(l1)
[1, 2, ['a', 'b', 'a']]
print(l3)
[1, 2, ['a', 'b', 'a']]
print(l4)
[1, 2, ['a', 'b']]
#l1[2].append('a')是改变l1内的可变列表的值,l1的id没有变化,值有变化,l3的值有变化,但是l4的值没有变化。
l1.append(3)
print(id(l1))
2030878621960
print(l1)
[1, 2, ['a', 'b', 'a'], 3]
print(l2)
[1, 2, ['a', 'b', 'a'], 3]
print(l3)
[1, 2, ['a', 'b', 'a']]
print(l4)
[1, 2, ['a', 'b']]
#l1.append(3)是改变l1的值,l1id没有变化,l3的值没有被改变(还是和上一步的值一样),l4与l1初始值一样的。

当改变 复杂子对象中的元素时,浅拷贝值发生了变化; 当改变的值不是复杂子对象,浅拷贝的值没有发生变化。因为 浅拷贝 ,复杂子对象的保存方式是 作为 引用 方式存储的,所以修改 浅拷贝的值 和原来的值都可以 改变 复杂子对象的值。
图解:

- 深度拷贝
- 即将被复制对象完全再复制一遍作为独立的新个体单独存在。所以改变原有被复制对象不会对已经复制出来的新对象产生影响
- 上图中已经有说明了。转载
python,可变对象,不可变对象,深拷贝,浅拷贝。的更多相关文章
- Python深复制浅复制or深拷贝浅拷贝
1. copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象.(比深拷贝更加节省内存)2. copy.deepcopy 深拷贝 拷贝对象及其子对象 用一个简单的例子说明如下: >& ...
- python集合增删改查,深拷贝浅拷贝
集合 集合是无序的,不重复的数据集合,它里面的元素是可哈希的(不可变类型),但是集合本身是不可哈希(所以集合做不了字典的键)的.以下是集合最重要的两点: 去重,把一个列表变成集合,就自动去重了. 关系 ...
- Python坑系列:可变对象与不可变对象
在之前的文章 http://www.cnblogs.com/bitpeng/p/4748148.html 中,大家看到了ret.append(path) 和ret.append(path[:])的巨大 ...
- python 可变、不可变类型、深拷贝、浅拷贝理解
简介 python中数据分为可变类型,不可变类型.不同的数据类型影响着不同情况下的深浅拷贝. 下面则将简要介绍一下 可变类型 当某个数据的值发生改变时,它对应的内存地址不发生改变,常见的有列表.字典. ...
- python引用在函数传参时的体现以及可变与不可变对象的对比
今天偶然看到 vamei 老师的博客 http://www.cnblogs.com/vamei/archive/2012/07/10/2582795.html 讲的是python动态类型以及引用的事儿 ...
- 关于python的可变和不可变对象
在python中所有都是对象,在python中只有list和dict是可变对象,其他都是不可变对象. 具体参照:http://www.cnblogs.com/lovemo1314/archive/20 ...
- python中的可变与不可变对象
Python中的可变对象和不可变对象 什么是可变/不可变对象 不可变对象,该对象所指向的内存中的值不能被改变.当改变某个变量时候,由于其所指的值不能被改变,相当于把原来的值复制一份后再改变,这会开辟一 ...
- python函数参数是值传递还是引用传递(以及变量间复制后是否保持一致):取决于对象内容可变不可变
函数参数传递本质上和变量整体复制一样,只是两个变量分别为形参a和实参b.那么,a=b后,a变了,b值是否跟着变呢?这取决于对象内容可变不可变 首先解释一下,什么是python对象的内容可变不可变? p ...
- Python中的可变、不可变对象和赋值技巧序列解包
可变对象和不可变对象 在python中一切皆对象.在Python中不存在所谓的值传递调用,一切传递都是对象的引用,也可认为是传址. python中,对象分为可变(mutable)和不可变(immuta ...
- python 基础使用list、dict、set、可变与不可变对象
参考链接:https://www.liaoxuefeng.com/wiki/1016959663602400/1017104324028448 dict是字典,可以储存键值对类型的值,set与dict ...
随机推荐
- 一次CMS GC问题排查过程(理解原理+读懂GC日志)
这个是之前处理过的一个线上问题,处理过程断断续续,经历了两周多的时间,中间各种尝试,总结如下.这篇文章分三部分: 1.问题的场景和处理过程:2.GC的一些理论东西:3.看懂GC的日志 先说一下问题吧 ...
- Dispatch Group
Dispatch Group A group of tasks that you monitor as a single unit. Overview Groups allow you to aggr ...
- 修改xampp-apache访问目录
文章转自 https://my.oschina.net/u/3618644/blog/1569972 问题来源: 一般情况下,每个项目占用一个根目录,而不是一个根目录下面有多个项目. 比如说,安装xa ...
- Sql Server2008如何让外网访问自己的数据库
1.打开 Sql Server配置管理器 2.修改Sql Server网络配置,将Tcp/IP协议修改为“已启用” 3.重启Sql Server服务即可(如果不知道怎么重启Sql Server服务,重 ...
- C语言之四舍五入
在C语言中,如果进行强制类型转换,它会将所需要取的位数直接提取出来,而其他位数的数字会被直接删除,不会对提取出来的位数有任何影响 所以如果我们需要提高精度,对所取的数进行四舍五入,需要给所需去的数的最 ...
- DEVOPS 运维开发系列
DEVOPS 运维开发系列四:ITIL事态管理流程.事态监控系统设计以及基于Devops的效率提升实践 - watermelonbig的专栏 - CSDN博客https://blog.csdn.net ...
- win10设置操作备忘
添加密码, 更改密码: Win键-->左侧用户图标-->更改帐户设置-->登陆选项-->添加密码 | 更改密码
- js中 ajax动态新增节点无法触发点击事件
在写ajax加载数据的时候发现,后面添加进来的demo节点元素,失去了之前的点击事件. 其实最简单的方法就是直接在标签中写onclick="",但是这样写有些场景的是实现不了的,最 ...
- 其它综合-运维老鸟分享linux运维发展路线规划
运维老鸟分享linux运维发展路线规划 linux 运维发展路线常见的就是下面两条路线: 第一条:运维应用-->系统架构-->运维开发-->系统开发 第二条:运维应用-->应用 ...
- idea中war和war exploded的区别及修改jsp必须重新启动tomcat才能生效的问题
刚开始使用idea,发现工程每次修改JS或者是JSP页面后,并没有生效,每次修改都需要重启一次Tomcat这样的确不方便.我想Idea肯定有设置的方法,不可能有这么不方便的功能存在. 需要在Tomca ...