深拷贝和浅拷贝的区别

  1. 浅拷贝
    copy函数是浅拷贝,只对可变类型的第一层对象进行拷贝,对拷贝的对象开辟新的内存空间进行存
    储,不会拷贝对象内部的子对象。

不可变类型的浅拷贝示例代码:

import copy # 使⽤浅拷⻉需要导⼊copy模块
# 不可变类型有: 数字、字符串、元组
a1 = 123123
b1 = copy.copy(a1) # 使⽤copy模块⾥的copy()函数就是浅拷⻉了
# 查看内存地址
print(id(a1))
print(id(b1))
print("-" * 10)
a2 = "abc"
b2 = copy.copy(a2)
# 查看内存地址
print(id(a2))
print(id(b2))
print("-" * 10)
a3 = (1, 2, ["hello", "world"])
b3 = copy.copy(a3)
# 查看内存地址
print(id(a3))
print(id(b3))

运行结果:

140459558944048
140459558944048
----------
140459558648776
140459558648776
----------
140459558073328
140459558073328

不可变类型的浅拷贝说明:

  • 通过上面的执行结果可以得知,不可变类型进行浅拷贝不会给拷贝的对象开辟新的内存空间,而 只是拷贝了这个对象的引用。

可变类型的浅拷贝示例代码:

import copy # 使⽤浅拷⻉需要导⼊copy模块
# 可变类型有: 列表、字典、集合
a1 = [1, 2]
b1 = copy.copy(a1) # 使⽤copy模块⾥的copy()函数就是浅拷⻉了
# 查看内存地址
print(id(a1))
print(id(b1))
print("-" * 10)
a2 = {"name": "张三", "age": 20}
b2 = copy.copy(a2)
# 查看内存地址
print(id(a2))
print(id(b2))
print("-" * 10)
a3 = {1, 2, "王五"}
b3 = copy.copy(a3)
# 查看内存地址
print(id(a3))
print(id(b3))
print("-" * 10)
a4 = [1, 2, [4, 5]]
# 注意:浅拷⻉只会拷⻉⽗对象,不会对⼦对象进⾏拷⻉
b4 = copy.copy(a4) # 使⽤copy模块⾥的copy()函数就是浅拷⻉了
# 查看内存地址
print(id(a4))
print(id(b4))
print("-" * 10)
# 查看内存地址
print(id(a4[2]))
print(id(b4[2]))
# 修改数据
a4[2][0] = 6
# ⼦对象的数据会受影响
print(a4)
print(b4)

运行结果:

139882899585608
139882899585800
----------
139882919626432
139882919626504
----------
139882919321672
139882899616264
----------
139882899587016
139882899586952
----------
139882899693640
139882899693640
[1, 2, [6, 5]]
[1, 2, [6, 5]]

可变类型的浅拷贝说明:

  • 通过上面的执行结果可以得知,可变类型进行浅拷贝只对可变类型的第一层对象进行拷贝,对拷
    贝的对象会开辟新的内存空间进行存储,子对象不进行拷贝。
  1. 深拷贝
    deepcopy函数是深拷贝, 只要发现对象有可变类型就会对该对象到最后一个可变类型的每一层对象就行
    拷贝, 对每一层拷贝的对象都会开辟新的内存空间进行存储。
    不可变类型的深拷贝示例代码:
import copy # 使⽤深拷⻉需要导⼊copy模块
# 不可变类型有: 数字、字符串、元组
a1 = 1
b1 = copy.deepcopy(a1) # 使⽤copy模块⾥的deepcopy()函数就是深拷⻉了
# 查看内存地址
print(id(a1))
print(id(b1))
print("-" * 10)
a2 = "张三"
b2 = copy.deepcopy(a2)
# 查看内存地址
print(id(a2))
print(id(b2))
print("-" * 10)
a3 = (1, 2)
b3 = copy.deepcopy(a3)
# 查看内存地址
print(id(a3))
print(id(b3))
print("-" * 10)

# 注意: 元组⾥⾯要是有可变类型对象,发现对象有可变类型就会该对象到最后⼀个可变类型的每⼀层对象进⾏
拷⻉
a4 = (1, ["李四"])
b4 = copy.deepcopy(a4)
# 查看内存地址
print(id(a4))
print(id(b4))
# 元组⾥⾯的可变类型⼦对象也会进⾏拷⻉
print(id(a4[1]))
print(id(b4[1]))

运行结果:

9289120
9289120
----------
140115621848320
140115621848320
----------
140115621859592
140115621859592
----------
140115602480584
140115621834568
140115602328136
140115602436168

不可变类型的深拷贝说明:
通过上面的执行结果可以得知:

  • 不可变类型进行深拷贝如果子对象没有可变类型则不会进行拷贝,而只是拷贝了这个对象的引用,否则会对该对象到最后一个可变类型的每一层对象就行拷贝*,对每一层拷贝的对象都会 开辟新的内存空间进行存储*

可变类型的深拷贝示例代码:

import copy # 使⽤深拷⻉需要导⼊copy模块
# 可变类型有: 列表、字典、集合
a1 = [1, 2]
b1 = copy.deepcopy(a1) # 使⽤copy模块⾥的deepcopy()函数就是深拷⻉了
# 查看内存地址
print(id(a1))
print(id(b1))
print("-" * 10)
a2 = {"name": "张三"}
b2 = copy.deepcopy(a2)
# 查看内存地址
print(id(a2))
print(id(b2))
print("-" * 10)
a3 = {1, 2}
b3 = copy.deepcopy(a3)
# 查看内存地址
print(id(a3))
print(id(b3))
print("-" * 10)
a4 = [1, 2, ["李四", "王五"]]
b4 = copy.deepcopy(a4) # 使⽤copy模块⾥的deepcopy()函数就是深拷⻉了
# 查看内存地址
print(id(a4))
print(id(b4))
# 查看内存地址
print(id(a4[2]))
print(id(b4[2]))
a4[2][0] = "王五"
# 因为列表的内存地址不同,所以数据不会收到影响
print(a4)
print(b4)

运行结果:

140348291721736
140348291721928
----------
140348311762624
140348311221592
----------
140348311457864
140348291752456
----------
140348291723080
140348291723144
140348291723208
140348291723016
[1, 2, ['王五', '王五']]
[1, 2, ['李四', '王五']]

可变类型的深拷贝说明:

  • 通过上面的执行结果可以得知, 可变类型进行深拷贝会对该对象到最后一个可变类型的每一层对象就行拷贝,对每一层拷贝的对象都会开辟新的内存空间进行存储。
  1. 浅拷贝和深拷贝的区别
  • 浅拷贝最多拷贝对象的一层
  • 深拷贝可能拷贝对象的多层
  1. 总结
  • 浅拷贝使用copy.copy函数

  • 深拷贝使用copy.deepcopy函数

  • 不管是给对象进行深拷贝还是浅拷贝,只要拷贝成功就会开辟新的内存空间存储拷贝的对象。

  • 浅拷贝和深拷贝的区别是:

    浅拷贝最多拷贝对象的一层,深拷贝可能拷贝对象的多层。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值