栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Python之深浅拷贝的本质

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python之深浅拷贝的本质

Python之深浅拷贝的本质
  • 文章目录
    • 前言
    • 对象的三个属性
    • 对象的深浅拷贝

文章目录 前言

近几年面试过程中,凡是说会Python的必会问到对象的深浅拷贝,这个问题也一直困扰了我许久,今天一起聊聊Python对象的深浅拷贝在内存中的实质

对象的三个属性

首先我们必须知道程序在运行过程中是在计算机内存中进行的,而程序又由多个对象组成,所以我们要知道Python对象有三个属性:id、type、value

  • id : 内存地址
  • type : 对象所存储的数据类型
  • value : 数据类型对应的值
>>> i = 5
>>> id(i)
140720048047920
>>> id(5)
140720048047920
>>> 
>>> type(i)

>>> i
5
>>> 

我们在赋值变量时,其实引用的就是内存中的一个数字地址编号,在使用对象时,由于这个数字地址不便于开发与记忆,所以统一用变量名来代替数字的地址,Python中万物皆对象,对象就有id、type、value。就像上图其实本质是将5的内存地址给了i。

对象的深浅拷贝
直接赋值:就是对象的引用(别名)
浅拷贝(copy):拷贝父对象,不拷贝父对象内部的子对象
深拷贝(deepcopy):copy模块的deepcopy方法,完全拷贝父对象及其子对象

接下来我们用力一个栗子来说明深浅拷贝在内存中的运行过程
浅拷贝

import copy

a = [4, 5, 6, [2, 5]]
b = a.copy().copy()
print("a的内存ID", id(a))
print("b的内存ID", id(b))
print("a:", a)
print("b:", b)
b.append(10)
b[3][0] = 3
print("浅拷贝之后的结果")
print("a:", a)
print("b:", b)

运行结果:

a的内存ID 1619660494208
b的内存ID 1619660491776
a: [4, 5, 6, [2, 5]]
b: [4, 5, 6, [2, 5]]
浅拷贝之后的结果
a: [4, 5, 6, [3, 5]]
b: [4, 5, 6, [3, 5], 10]

a在内存中的地址引用如下
执行完 b = a.copy().copy()后内存地址变化如下
执行完 b.append(10)的内存地址如下
所以这个时候a是没变的,b发生了变化
接下来执行 b[3][0] = 3,内存地址引用变化如下
应为是引用的子对象发生了变化,所以a和b都发生改变

a: [4, 5, 6, [2, 5]]
b: [4, 5, 6, [2, 5]]
浅拷贝之后的结果
a: [4, 5, 6, [3, 5]]
b: [4, 5, 6, [3, 5], 10]

深拷贝

c = [4, 5, 6, [2, 5]]
d = copy.deepcopy(c)
print("c的内存ID", id(c))
print("d的内存ID", id(d))
print("c:", c)
print("d:", d)
d.append(10)
d[3][0] = 3
print("深拷贝之后的结果")
print("c:", c)
print("d:", d)

c = [4, 5, 6, [2, 5]]
执行后内存地址的引用如下
d = copy.deepcopy( c )
d.append(10)
d[3][0] = 3
运行结果:

c的内存ID 1619660492032
d的内存ID 1619660399872
c: [4, 5, 6, [2, 5]]
d: [4, 5, 6, [2, 5]]
深拷贝之后的结果
c: [4, 5, 6, [2, 5]]
d: [4, 5, 6, [3, 5], 10]

相信到这里,小伙伴们已经看懂了内存地址的不断引用的过程。总结下:使用copy都是浅拷贝,只是拷贝了父级对象的内存地址引用,没有逐一拷贝子级的内存地址引用,而deepcopy是深拷贝,直接递归拷贝了所有的引用。所以当改变子级别的可变对象的引用地址时,浅拷贝出来的对象和原来的都会发生改变,而深拷贝不会受影响,是两个完全独立的个体。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/445569.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号