Python深浅拷贝、垃圾回收机制
1.Python中的可变和不可变数据类型有哪些?
不可变类型:
- 数值型:int,float,complex,bool
- 字符串:str
- 元组: tuple
- 冻结集合:frozenset(不可增删元素)
可变类型
-
列表(list)、字典(dict)、集合(set)、自定义对象、多数第三方容器。
-
可变数据类型修改原来的值内存空间地址不变
-
不可变数据类型修改原来的值内存空间地址会改变
-
在Python中可变类型和不可变类型的区分依据就是当当前值被修改后的内存空间地址是否改变
2.Python是值传递还是引用传递
- 值传递 每一次的值都会有一个自己的内存空间地址
- 引用传递 是在中间有一块内存地址负责中转对应的值
- 严格意义上来说,Python既不是值传递,也不是引用传递,python是自己的传递方式
3.垃圾回收机制
3.1 什么是垃圾回收机制
- 垃圾回收机制(简称GC)是Python解释器自带的一种机制
- 专门用来回收不可用的变量值所占用的内存空间(在内存中,没有变量名指向的数据都是垃圾数据)
3.2为什么要有垃圾回收机制
- 程序运行过程中会申请大量的内存空间,而对于一些无用的内存空间如果不及时清理的话会导致内存使用殆尽(内存溢出),导致程序崩溃
Python将变量值(即对象)存放于堆区,主要是为了提供灵活的内存分配、支持对象共享以及实现自动化的垃圾回收,这些特性对于编写高效、健壮的Python程序至关重要。
变量本身作为对象的引用,则通常存储在栈区,便于快速访问和管理其生命周期。
4.垃圾回收机制原理
- 引用计数为主,分代回收、标记清除为辅。
- Python的GC模块主要运用了“引用计数”(reference counting)来跟踪和回收垃圾。
- 在引用计数的基础上,还可以通过“标记-清除”(mark and sweep)解决容器对象可能产生的循环引用的问题,并且通过“分代回收”(generation collection)以空间换取时间的方式来进一步提高垃圾回收的效率。
4.深浅拷贝
- 深拷贝是指创建一个新的对象,该对象与原始对象完全独立,并且新对象和源对象中对可变数据类型的引用不一致了
- 换句话说,它会递归地复制所有嵌套对象,包括它们的内容,以便我们在修改新对象时不会影响到原始对象。
- 浅拷贝是指创建一个新对象,并将原始对象的元素复制到新对象中,并且新对象和源对象中对可变数据类型的引用一致。
- 然而如果原始对象包含可变的对象(如列表),则新对象中的这些元素仍然与原始对象中相应元素共享相同的内存地址。
4.1 深浅拷贝的作用:
- 深浅拷贝是用来复制对象的
- 如果是 浅拷贝 只会复制一层
- 如果是 深拷贝 完整复制
4.2浅拷贝
- 借助内置模块 copy
import copy
original_list = [1, 2, 3, 4, 5, 6]
shallow_copy_list = copy.copy(original_list)
original_list.append(9)
shallow_copy_list.append(8)
print(f"原来的列表 :>>>> {original_list}")
print(f"浅拷贝的列表 :>>>> {shallow_copy_list}")
# 原来的列表 :>>>> [1, 2, 3, 4, 5, 6, 9]
# 浅拷贝的列表 :>>>> [1, 2, 3, 4, 5, 6, 8]
original_list = [1, 2, 3, [7, 8, 9]]
shallow_copy_list = copy.copy(original_list)
print(shallow_copy_list) # [1, 2, 3, [7, 8, 9]]
original_list[3][-1] = 999
print(f"原来的列表 :>>>> {original_list}")
print(f"浅拷贝的列表 :>>>> {shallow_copy_list}")
# 原来的列表 :>>>> [1, 2, 3, [7, 8, 999]]
# 浅拷贝的列表 :>>>> [1, 2, 3, [7, 8, 999]]
4.3深拷贝
import copy
original_list = [1, 2, 3, [7, 8, 9]]
shallow_copy_list = copy.deepcopy(original_list)
print(shallow_copy_list) # [1, 2, 3, [7, 8, 9]]
# 修改原列表中的 可变数据类型中的元素
original_list[3][-1] = 999
print(f"原来的列表 :>>>> {original_list}")
print(f"深拷贝的列表 :>>>> {shallow_copy_list}")
# 原来的列表 :>>>> [1, 2, 3, [7, 8, 999]]
# 深拷贝的列表 :>>>> [1, 2, 3, [7, 8, 9]]
# 【总结】
# 深拷贝就是创建一个完全独立的对象,并且递归的复制对象中的所有关系
# 浅拷贝就是创建一个新对象,但是新对象共享源对象中的关联关系

浙公网安备 33010602011771号