Python浅拷贝深拷贝之copy、deepcopy

liftword4个月前 (03-01)技术文章40

笔记记录20221205:


个人总结:

1,两者基本区别不大;

2,在涉及到子对象时候,两者才有区别;

3,在涉及到子对象,且子对象的操作后内存地址没有发生变化(如下方代码:dic1['one'].append(4)),这时才有区别,即复制后的新对象,是copy的会发生变化、是deepcopy的不会发生变化

# 浅拷贝(copy()):拷贝父对象,不会拷贝对象内部的子对象。例子如下:
# 列表举例:li2进行copy了li1,li1变化,li2不会变化:
li1 = [1,2,3]
li2 = li1.copy()
print('li1:',li1,'li2:',li2) # li1: [1, 2, 3] li2: [1, 2, 3]
li1.append(4)
print('li1:',li1,'li2:',li2) # li1: [1, 2, 3, 4] li2: [1, 2, 3]


# 但是在上面的例子中看不出子对象父对象关系,那我们用下面这个例子:
'''
总结:
1,父对象发生了变化,复制后的新对象不会发生变化
2,当父对象没有发生变化,仅仅只是子对象发生了变化:
    2.1,子对象的内存地址没有变化,那么复制后的新对象会发生变化
    2.2,子对象的内存地址有变化,那么复制后的新对象不会发生变化
'''
# 字典举例:
dic1 = {'one':[1,2,3],'two':[4,5,6]}
dic2 = dic1.copy()
# dic1: 2488946315520 {'one': [1, 2, 3], 'two': [4, 5, 6]}
# dic2: 2488946315520 {'one': [1, 2, 3], 'two': [4, 5, 6]},
# dic1和dic2是独立的对象,但是它们的子对象[1,2,3]还是指向统一的对象,内存地址
print('dic1:',id(dic1['one']),dic1,'dic2:',id(dic2['one']),dic2)


# 2,当父对象没有发生变化,仅仅只是子对象发生了变化:
    # 2.1,子对象的内存地址没有变化,那么复制后的新对象会发生变化
# 直接append,虽然子对象发生了变化,但是因为2.1:子对象的内存地址没有变化,那么dic2的键one的值,也随之发生改变
dic1['one'].append(4)
# dic1: 2488946315520 {'one': [1, 2, 3, 4], 'two': [4, 5, 6]}
# dic2: 2488946315520 {'one': [1, 2, 3, 4], 'two': [4, 5, 6]}
print('dic1:',id(dic1['one']),dic1,'dic2:',id(dic2['one']),dic2)


# 2,当父对象没有发生变化,仅仅只是子对象发生了变化:
#     2.2,子对象的内存地址有变化,那么复制后的新对象不会发生变化
# 直接对字典对象进行操作,对one键进行重新赋值,那么满足2.2:子对象的内存地址有变化,这时dic2不会发生变化
dic1['one'] = [7,8,9]
# dic1: 2043613030208 {'one': [7, 8, 9], 'two': [4, 5, 6]}
# dic2: 2043612942528 {'one': [1, 2, 3, 4], 'two': [4, 5, 6]}
print('dic1:',id(dic1['one']),dic1,'dic2:',id(dic2['one']),dic2)


# 1,父对象发生了变化,复制的对象不会发生变化
dic3 = {'one':[1,2,3],'two':[4,5,6]}
dic4 = dic3.copy()
# 直接对字典对象进行操作,新增一个键值对,这时dic2不会发生变化
dic3['three'] = [7,8]
# dic3: {'one': [1, 2, 3], 'two': [4, 5, 6], 'three': [7, 8]}
# dic4: {'one': [1, 2, 3], 'two': [4, 5, 6]}
print('dic3:',dic3,'dic4:',dic4)


# 1,父对象发生了变化,复制的对象不会发生变化
dic5 = {'one':[1,2,3],'two':[4,5,6]}
dic6 = dic5.copy()
dic5.popitem() # 删除最后一个键值对
# dic5: {'one': [1, 2, 3]}
# dic6: {'one': [1, 2, 3], 'two': [4, 5, 6]}
print('dic5:',dic5,'dic6:',dic6)


# 深拷贝(deepcopy()):是copy模块中的方法,完全拷贝了子对象和父对象,例子如下:
# 深度拷贝, dic8完全拷贝了dic7父对象及其子对象,两者是完全独立的
from copy import deepcopy
dic7 = {'one':[1,2,3],'two':[4,5,6]}
dic8 = deepcopy(dic7)
dic7['one'].append(4)
# dic7: {'one': [1, 2, 3, 4], 'two': [4, 5, 6]}
# dic8: {'one': [1, 2, 3], 'two': [4, 5, 6]}
print('dic7:',dic7,'dic8:',dic8)



相关文章

用Python复制文件的9个方法_python怎么复制文件到另一个地方

Python 中有许多“开盖即食”的模块(比如 os,subprocess 和 shutil)以支持文件 I/O 操作。在这篇文章中,你将会看到一些用 Python 实现文件复制的特殊方法。下面我们开...

Python 文件复制必备技巧:保留原数据、递归复制目录,效果惊艳

引言:使用 shutil 模块来拷贝文件夹下的所有内容到指定目录。会递归地拷贝整个目录及其所有内容(包括子目录和文件)Python 3.8 或更高版本import shutil import os...

Python复制文件的9种办法 :一文全。

Python复制文件 11 分钟阅读将文件从一个目录复制到另一个目录是一项常见的任务。Python 有许多模块(如 os、subprocess 和 sh-util)来支持文件复制。从这篇文章中,可以获...

Python3导入自定义模块的3种方式_python导入自定义的py文件

开始第一种,直接 import这里有个大前提,就是你的py执行文件和模块同属于同个目录(父级目录),如下图:main.py 和 pwcong模块同在python目录执行文件为main.pypwcong...

Python Flask 全流程全栈项目实战(完结)

获课:97java.xyz/4964/Python Flask 全流程全栈项目实战指南(完结)在当今快速发展的Web开发领域,Python Flask以其简洁、灵活和易扩展的特点,成为了众多开发者首选...

python应用-shutil详解文件复制/移动/删除功能

shutil 模块是 Python 的标准库模块(直接导入,无需下载),提供了像在电脑上操作文件、文件夹的功能,如复制、移动、删除文件和文件夹等。shutil 模块的__all__包含的函数如下:复制...