IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> 2021-10-10 -> 正文阅读

[Python知识库]2021-10-10

python 赋值、浅拷贝和深拷贝

本文从以下三个方面来对python中的直接赋值、浅拷贝和深拷贝进行解析:

  1. 基本概念
  2. 图解
  3. 实例

1. 基本概念

赋值(a=b):只拷贝了对象的引用,没有拷贝内容。变量a和b指向相同的内存地址,相当于同一数据块打上了a、b两个标签。
浅拷贝(a=copy.copy(b)):a只拷贝b的父对象,不会拷贝b中的子对象。
深拷贝(a=copy.deepcopy()):a拷贝了b的父对象及其子对象。

2. 图解

2.1 直接赋值:b=a, 只是复制了对象的引用,不会开辟新的内存空间。a和b都指向同一个对象。

在这里插入图片描述

2.2 浅拷贝:b=copy.copy(a),a和b均为独立的对象,但他们的子对象指向同一对象。
在这里插入图片描述

2.3 深拷贝:b=copy.deepcopy(a),a 和 b 完全拷贝了父对象及其子对象,两者是完全独立。
在这里插入图片描述
3.实例

#直接赋值
a={1:[1,2,3]}
b=a
#查看b的值
print("b的值是:",b)
#使用id()函数获取对象a和b的内存地址
print("a的内存地址是:",id(a))
print("b的内存地址是:",id(b))

运行结果:
b的值是: {1: [1, 2, 3]}
a的内存地址是:60733272
b的内存地址是:60733272

#直接赋值
a=[1,2,3]
b=a
print("a的内存地址是:",id(a))
print("b的内存地址是:",id(b))
b[0]=11
print("a的值变为:",a)

运行结果:
a的内存地址是: 61951208
b的内存地址是: 61951208
a的值变为:[11, 2, 3]

从上面实例中可以看出,直接赋值时只是复制了新对象的引用,不会开辟新的内存空间,两个对象指向同一内存地址。赋值只是将原有的数据块打上一个新标签,所以当其中一个标签被改变的时候,数据块就会发生变化,另一个标签也会随之改变。

#浅拷贝
import copy
a={1:[1,2,3]}
b=copy.copy(a)
#查看b的值
print("b的值是:",b)
#使用id()函数获取对象a和b的内存地址
print("a的内存地址是:",id(a))
print("b的内存地址是:",id(b))

运行结果:
b的值是: {1: [1, 2, 3]}
a的内存地址是:60733312
b的内存地址是:60733432

#浅拷贝
import copy
a=[1,2,[3,33]]
b=copy.copy(a)
print("b的值是:",b)
#使用id()函数获取对象a和b的内存地址
print("a的内存地址是:",id(a))
print("b的内存地址是:",id(b))
b[1]=222
print("改变父对象后a的值是:",a)
b[2][0]=0
print("改变子对象后a的值是:",a)

运行结果:
b的值是: [1, 2, [3, 33]]
a的内存地址是: 61951592
b的内存地址是: 61951528
改变父对象后a的值是: [1, 2, [3, 33]]
改变子对象后a的值是: [1, 2, [0, 33]]

从上面实例可看出,在浅拷贝中a 和 b 是一个独立的对象,指向不同的内存地址。但他们的子对象还是指向同一对象。

#深拷贝
import copy
a={1:[1,2,3]}
b=copy.deepcopy(a)
#查看b的值
print("b的值是:",b)
#使用id()函数获取对象a和b的内存地址
print("a的内存地址是:",id(a))
print("b的内存地址是:",id(b))

运行结果:
b的值是: {1: [1, 2, 3]}
a的内存地址是:60733272
b的内存地址是:61993360

#深拷贝
import copy
a=[1,2,[3,33]]
b=copy.deepcopy(a)
print("b的值是:",b)
#使用id()函数获取对象a和b的内存地址
print("a的内存地址是:",id(a))
print("b的内存地址是:",id(b))
b[1]=222
print("改变父对象后a的值是:",a)
b[2][0]=0
print("改变子对象后a的值是:",a)

运行结果:
b的值是: [1, 2, [3, 33]]
a的内存地址是: 61951624
b的内存地址是: 61951688
改变父对象后a的值是: [1, 2, [3, 33]]
改变子对象后a的值是: [1, 2, [3, 33]]

从上面深拷贝的实例可以看出,与浅拷贝对应,深拷贝拷贝了对象的所有元素,包括多层嵌套的元素。深拷贝完全拷贝了父对象及其子对象,两者是完全独立、互不影响。

注意:浅拷贝和深拷贝需导入copy模块

几个概念:

  1. 变量:可以看成一个小箱子,专门用来“盛装”程序中的数据。每个变量都拥有独一无二的名字,拥有指向对象的连接空间,通过变量的名字就能找到变量中的数据;
  2. 对象:被分配的一块内存,存储其所代表的值;
  3. 引用:是自动形成的从变量到对象的指针;
  4. 类型:属于对象,而非变量;
  5. 不可变对象:一旦创建就不可修改的对象,包括字符串、元组、数值类型(该对象所指向的内存中的值不能被改变。当改变某个变量时,由于其所指的值不能被改变,相当于把原来的值复制一份后再改变,这会开辟一个新的地址,变量再指向这个新的地址);
  6. 可变对象:可以修改的对象,包括列表、字典、集合(该对象所指向的内存中的值可以被改变。变量(准确的说是引用)改变后,实际上是其所指的值直接发生改变,并没有发生复制行为,也没有开辟新的地址,通俗点说就是原地改变)。

写在最后

以上内容就是本文的全部内容了,希望对学习路上的你有所帮助,一起进步呀~

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2021-10-11 17:28:47  更:2021-10-11 17:29:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 18:52:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码