Python深拷贝、浅拷贝(个人笔记)

本文详细探讨了Python中的深拷贝和浅拷贝概念,包括对象的属性、可变与不可变对象的区别。对于不可变对象,赋值、浅拷贝和深拷贝均指向同一地址,而可变对象则有所不同。浅拷贝只拷贝父对象,不拷贝子对象,而深拷贝则会完全拷贝包括子对象在内的所有内容,确保修改不会互相影响。Python中实现浅拷贝的方式有多种,而深拷贝通常使用`copy.deepcopy`函数完成。
摘要由CSDN通过智能技术生成

Python中的深拷贝和浅拷贝

Python中的对象

Python中构造的任何数据类型都是一个对象。

每个对象都包含三个属性:

  • 身份

  • 类型

name = "Li"
print(id(name))  # 2770749417776
print(type(name))  # <class 'str'>
print(name)  # Li

Python中的可变对象和不可变对象

可变对象:list,dict,set。指对象的值可变,身份不可变。

不可变对象:int,float,str,tuple。指对象的值和身份均不可变。如果新创建的对象关联到原来的变量名,就对象会被丢弃,垃圾回收期会在适当的实际回收这些对象。

a = [1, 2]  # 可变对象
print(id(a))  # 2057274282376
a.append(3)
print(id(a))  # 2057274282376
# 可变对象的内容发生改变,但是身份不变
​
name = "Li"  # 不可变对象
print(id(name))  # 2057279105328
name = "Lei"
print(id(name))  # 2057279105584
# 不可变对象的值发生改变,对应的身份也发生改变。

总的来说,Python中的不可变对象和C++中的常量比较接近,每个对象在内存中的地址相对固定的。

补充:

关于不可变对象int:

  • 对于小整数[-5, 256],考虑到小整数可能频繁使用,出于性能考虑,python使用小整数对象缓冲池small_ints缓存了[-5, 257)之间的整数,该范围内的整数在Python系统中是共享的。小整数对象在程序启动过程中初始化,小整数对象的引用计数变量ob_refcnt(引用计数记录指向对象引用的个数,当变为0,则被释放)不会改变且永远>0。

  • 对于超出了[-5, 257)之间的其他整数,Python同样提供了专门的缓冲池(通用整数对象的缓冲池),供这些所谓的大整数使用,避免每次使用的时候都要不断的malloc分配内存带来的效率损耗。

  • 整数对象回收时,内存不会归还给系统,而是将对象的ob_type指向free_list,供新创建的对象使用。

关于可变对象:

  • Python中参数传递都是传递引用。但是对于可变类型和不可变类型有所区别:传入参数为可变类型,函数内部修改就会影响函数外部的变量;若传入参数为不可变类型,在函数内部修改改变量并不会影响函数外部的变量,因为修改的时候会先复制一份再修改?

Python中的浅拷贝和深拷贝

直接赋值

Python中直接赋值得到的是对象的引用。

浅拷贝

拷贝父对象,不会拷贝对象的内部子对象。

深拷贝

完全拷贝父对象及其子对象。因此原对象的任何改变都不回对拷贝对象有任何影响,相当于重新开辟内存,将原对象的数据拷贝进去。

  • 对于不可变对象,赋值、浅拷贝和深拷贝后均指向同一个地址,拷贝前后不会互相影响。

  • 对于可变对象:

    • 赋值就是引用,变量之间会相互影响;

    • 浅拷贝得到的新对象的地址和原对象不同,但是新对象里面的可变对象(如列表)的地址和原对象里的可变对象的地址是相同的。也就是说浅拷贝它拷贝的是浅层次的数据结构(不可变对象),对象里的可变对象作为深层次的数据结构并没有被拷贝到新地址里面去,而是和原对象里的可变对象指向同一个地址,所以在新对象或原对象里对这个可变对象做修改时,两个对象是同时改变的。

    • 深拷贝会另外开辟一个内存空间,拷贝原对象,所以原对象做任何的改变都不会影响深拷贝后的对象。

实现方式:

  • 浅拷贝在Python中有多种方式实现,如copy模块的copy函数、对象的copy函数、工厂方法、切片等;大多数情况下,编写程序时都是使用浅拷贝,除非有特定的需求。浅拷贝的优点:拷贝速度快,占用空间少,拷贝效率高。

  • 深拷贝一般通过copy模块的copy.deepcopy实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值