Python 浅拷贝(shallow copy)和 深拷贝(deep copy)的区别

2023-11-28 10:32

本文主要是介绍Python 浅拷贝(shallow copy)和 深拷贝(deep copy)的区别,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

深拷贝和浅拷贝都是对对象进行复制生成一个相同对象的过程,它们的本质区别是拷贝出来的对象的地址是否和原对象一样

 

拷贝对象分为两种:可变对象和不可变对象

可变对象(列表,字典):指一个对象在不改变内存所指地址的前提,改变元素的值

不可变对象(数字,字符串,元组):对象的值修改后,对象内存所指的地址也会相应发生改变

 

浅拷贝:
  是指复制过程中,只复制一层变量,不会复制深层变量绑定的对象的复制过程

深拷贝:

      是指复制过程中,复制深层变量绑定的对象的复制过程

当拷贝对象为不可变对象时,不管是copy(浅拷贝)还是deepcopoy(深拷贝),新对象和原有对象的ID指向的都是同一个地址,和赋值(=)的情况一样,举例说明:

import copycopy_str = 'hello word'
copy_str1 = copy.copy(copy_str)#浅拷贝
copy_str2 = copy.deepcopy(copy_str)#深拷贝print(id(copy_str))
print(id(copy_str1))
print(id(copy_str2))#结果:
#11936352
#11936352
#11936352

打印结果是一样的,自己可以试验一下原对象数据类型为元组和数字的情况,结果是一样的;

 

当拷贝对象为可变类型时,还要分两种情况,第一种是原对象为单层结构(对象中无复杂子元素,如:[1,2,3]),第二种是原对象为多层结构(对象中有复杂子对象,如:列表的子元素为列表,[1,[2],3)

第一种情况(原对象为单层结构):拷贝的对象无复杂子对象,无论是copy(浅拷贝)还是deepcopoy(深拷贝),原对象的值发生改变不会影响新对象的值,同时新对象的值发生改变也不会影响原来对象的值,原来对象的ID和新对象的ID不同,如:

import copycopy_list = [1,2]
copy_list1 = copy.copy(copy_list)
copy_list2 = copy.deepcopy(copy_list)print(id(copy_list),id(copy_list1),id(copy_list2))#结果
#50722336 50722296 50722256

可以对新对象和原有对象进行修改操作,看是否会影响其他对象的值;

 

第二种情况(原对象为多层结构,这是重点) :拷贝对象有复杂子对象,使用copy进行浅拷贝时,改变原来对象中复杂子对象元素的值时,新对象中对应的值也会相应发生改变,同理,改变新对象中复杂子对象的元素的值,原来对象对应的值也会发生改变,使用deepcopy进行拷贝时,完全复制独立,修改互不影响对应的值

import copycopy_list = [[1],2]
copy_list1 = copy.copy(copy_list)#浅拷贝
copy_list2 = copy.deepcopy(copy_list)#深拷贝
print(id(copy_list),id(copy_list1),id(copy_list2))
#结果
#52168224 52168184 52168144copy_list[0][0] = 10
print(copy_list,copy_list1)
#结果
[[10], 2] [[10], 2]copy_list1[0][0] = 5
print(copy_list,copy_list1)
#结果
[[5], 2] [[5], 2]print(id(copy_list[0][0]),id(copy_list1[0][0]))
#结果
#1355965648 1355965648copy_list[0][0] = 10
print(copy_list,copy_list2)
#结果
[[10], 2] [[1], 2]copy_list2[0][0] = 5
print(copy_list,copy_list2)
#结果,现在copy_list的第一个值为10,是因为上面修改的原因,也可以使用不改变的copy_list,值则为1
[[10], 2] [[5], 2]print(id(copy_list[0][0]),id(copy_list2[0][0]))
#结果
#1355965648 1355965584

 

通过代码得到验证,通过浅拷贝(copy)复制,原来对象和新对象的复杂子元素的ID是一样的,而通过深拷贝(deepcopy)复制,原来对象和新对象的复杂子元素的ID是不一样的

注意事项:

深拷贝通常只对可变对象进行深层复制,不可变对象通常不会被复制。(复制的是对象的单层结构,深层对象是引用)

 

 

 

 

 

 

 

 

 

 

 

 

 

这篇关于Python 浅拷贝(shallow copy)和 深拷贝(deep copy)的区别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/429549

相关文章

Python将博客内容html导出为Markdown格式

《Python将博客内容html导出为Markdown格式》Python将博客内容html导出为Markdown格式,通过博客url地址抓取文章,分析并提取出文章标题和内容,将内容构建成html,再转... 目录一、为什么要搞?二、准备如何搞?三、说搞咱就搞!抓取文章提取内容构建html转存markdown

Python获取中国节假日数据记录入JSON文件

《Python获取中国节假日数据记录入JSON文件》项目系统内置的日历应用为了提升用户体验,特别设置了在调休日期显示“休”的UI图标功能,那么问题是这些调休数据从哪里来呢?我尝试一种更为智能的方法:P... 目录节假日数据获取存入jsON文件节假日数据读取封装完整代码项目系统内置的日历应用为了提升用户体验,

Python FastAPI+Celery+RabbitMQ实现分布式图片水印处理系统

《PythonFastAPI+Celery+RabbitMQ实现分布式图片水印处理系统》这篇文章主要为大家详细介绍了PythonFastAPI如何结合Celery以及RabbitMQ实现简单的分布式... 实现思路FastAPI 服务器Celery 任务队列RabbitMQ 作为消息代理定时任务处理完整

Python Websockets库的使用指南

《PythonWebsockets库的使用指南》pythonwebsockets库是一个用于创建WebSocket服务器和客户端的Python库,它提供了一种简单的方式来实现实时通信,支持异步和同步... 目录一、WebSocket 简介二、python 的 websockets 库安装三、完整代码示例1.

揭秘Python Socket网络编程的7种硬核用法

《揭秘PythonSocket网络编程的7种硬核用法》Socket不仅能做聊天室,还能干一大堆硬核操作,这篇文章就带大家看看Python网络编程的7种超实用玩法,感兴趣的小伙伴可以跟随小编一起... 目录1.端口扫描器:探测开放端口2.简易 HTTP 服务器:10 秒搭个网页3.局域网游戏:多人联机对战4.

Springboot @Autowired和@Resource的区别解析

《Springboot@Autowired和@Resource的区别解析》@Resource是JDK提供的注解,只是Spring在实现上提供了这个注解的功能支持,本文给大家介绍Springboot@... 目录【一】定义【1】@Autowired【2】@Resource【二】区别【1】包含的属性不同【2】@

使用Python实现快速搭建本地HTTP服务器

《使用Python实现快速搭建本地HTTP服务器》:本文主要介绍如何使用Python快速搭建本地HTTP服务器,轻松实现一键HTTP文件共享,同时结合二维码技术,让访问更简单,感兴趣的小伙伴可以了... 目录1. 概述2. 快速搭建 HTTP 文件共享服务2.1 核心思路2.2 代码实现2.3 代码解读3.

Java中的String.valueOf()和toString()方法区别小结

《Java中的String.valueOf()和toString()方法区别小结》字符串操作是开发者日常编程任务中不可或缺的一部分,转换为字符串是一种常见需求,其中最常见的就是String.value... 目录String.valueOf()方法方法定义方法实现使用示例使用场景toString()方法方法

Python使用自带的base64库进行base64编码和解码

《Python使用自带的base64库进行base64编码和解码》在Python中,处理数据的编码和解码是数据传输和存储中非常普遍的需求,其中,Base64是一种常用的编码方案,本文我将详细介绍如何使... 目录引言使用python的base64库进行编码和解码编码函数解码函数Base64编码的应用场景注意

Python基于wxPython和FFmpeg开发一个视频标签工具

《Python基于wxPython和FFmpeg开发一个视频标签工具》在当今数字媒体时代,视频内容的管理和标记变得越来越重要,无论是研究人员需要对实验视频进行时间点标记,还是个人用户希望对家庭视频进行... 目录引言1. 应用概述2. 技术栈分析2.1 核心库和模块2.2 wxpython作为GUI选择的优