浅析Python中的赋值和深浅拷贝
python中,A object = B object 是一种赋值操作,赋的值不是一个对象在内存中的空间,而只是这个对象在内存中的位置 。
此时当B对象里面的内容发生更改的时候,A对象也自然而然的会跟着更改。
name = ["root","admin"] cp_name = name # 对cp_name进行赋值操作 # 对name列表进行插入 name.append('root_temp') print(name,cp_name) # ['root', 'admin', 'root_temp'] ['root', 'admin', 'root_temp'] print(id(name),id(cp_name)) # 23991960 23991960
而想要进行浅拷贝或者深拷贝,就需要引入copy模块 。
首先来说下浅拷贝,当进行浅拷贝时,使用copy.copy()方法。
import copy name = ["root","admin"] # 进行浅拷贝操作 cp_name = copy.copy(name) # 查看cp_name,name print(name,cp_name) # ['root', 'admin'] ['root', 'admin'] 拷贝成功 #查看地址 print(id(name),id(cp_name)) # 21146920 21147160 内存地址并不相同 # 尝试对name进行更改 name.append('root_temp') # 查看cp_name是否更改 print(cp_name) # ['root', 'admin'] 内容并没有更改
A = copy.copy(B) 此时A对象相当于把B对象中的内容给完成的拷贝了一份,存储在了一份新的内存地址当中。
其中有一点需要注意,如下:
import copy name = ['root','admin',['root_temp','admin_temp']] cp_name = copy.copy(name) # 查看两个对象的地址 print(id(name),id(cp_name)) # 24358504 24428952 二者的地址并不相同 # 对name 进行更改 name.append('test') # 查看cp_name是否更改 print(cp_name) # ['root', 'admin', ['root_temp', 'admin_temp']] cp_name并未更改 # 在来对name中的列表对象进行更改 name[2].append('ttttt') print(cp_name) # ['root', 'admin', ['root_temp', 'admin_temp', 'ttttt']] 发现cp_name内容发生了变化
在上面的代码中,通过copy.copy()方法把name对象浅拷贝给了cp_name,此时二者的内容相同,但是地址不同,说明通过浅拷贝后,cp_name相当于重新开辟了一块内存空间用来存储拷贝过来的内容。所以说,当name.append()第一次插入值的时候,cp_name对象没有变化,因为cp_name和name 处于两个不同的内存空间,是独立的。
而浅拷贝的问题在于,只能够拷贝第一层的内容,至于说第二层以及第三层或者第n层,对于浅拷贝来说都是无能为力的,只能简单的拷贝一份内存地址。
所以说,对于name 这个对象中,列表第一层发生更改,是不会影响cp_name的,而一旦更改了第二层或者第n层的内容,cp_name都会被影响,因为此时的cp_name对象里面子列表是与name的子列表共享相同的内存空间。
而如果想要对第一层以及第二层甚至第n层都进行彻底的拷贝,那么就需要使用深层拷贝。
深层拷贝需要使用copy模块的deepcopy()方法。
import copy name = ['root','admin',['root_temp','admin_temp']] cp_name = copy.deepcopy(name) # 查看二者的id print(id(name),id(cp_name)) # 29863528 29933976 地址不同,说明开辟了处于两块不同的空间 # 对name 第一层以及第二层进行更改 name.append('t1') name[2].append('t2') # 查看cp_name是否内容发生变化 print(cp_name) # ['root', 'admin', ['root_temp', 'admin_temp']] 内容并未发生更改
此时,cp_name对象并不会被name所影响,无论name对象的第一层列表还是第n层的更改和变化,都不会影响cp_name,因为此时通过深层拷贝,两个对象已经完全的处于两个不同的独立内存空间,而这也就是深层拷贝。
总结
以上所述是小编给大家介绍的Python中的赋值和深浅拷贝,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 文件操作——编码
- MySQL binlog后面的编号最大是多大?
- 文件操作——其他
- VBA调用外部对象01:字典Dictionary(去除重复数据)
- 等保测评2.0:应用身份鉴别
- 文件操作——读取
- YAML,另一种标记语言?不止是标记语言!
- Canal binlog 日志管理器与GTID简介
- RNA-Seq的Counts和FPKM数据如何转换成TPM?
- Java代码审计基础之反射
- 手把手教你用Python开发“剪刀石头布”小游戏【附源码】
- For语句
- 使用go语言制作dll封装Sprintf函数给VBA使用
- 同事埋了个坑:Insert into select语句把生产服务器炸了
- VBA使用API_01:读取文件