强引用和弱引用
- 强引用:就像你拥有这本书。只要书在你手里,它就绝不会被丢掉。在Python中,变量名(如 a = [1, 2])、列表包含对象等,都是强引用。只要有一个强引用存在,对象就不会被垃圾回收。
- 弱引用:就像你在这本书上贴了张便签,上面写着“图书馆的某本书”。便签本身不“拥有”那本书。如果图书馆把那本书回收或借走了(对象被垃圾回收了),你的便签就指向了一个不存在的目标(返回 None)。它不阻止垃圾回收。
代码示例:
import weakref
import sys
class Data:
def __del__(self):
print(f"Data 对象被回收了!")
# 1. 强引用示例
print("=== 强引用示例 ===")
obj1 = Data() # 创建一个对象,obj1是对它的强引用
ref_count_1 = sys.getrefcount(obj1) - 1 # 获取引用计数(需减1因getrefcount本身会产生一个临时引用)
print(f"创建后引用计数: {ref_count_1}") # 输出: 1
obj2 = obj1 # obj2 是另一个强引用
print(f"赋值后引用计数: {sys.getrefcount(obj1) - 1}") # 输出: 2
del obj1 # 删除一个强引用,计数减1
print(f"删除obj1后引用计数: {sys.getrefcount(obj2) - 1}") # 输出: 1
# 此时对象不会被回收,因为obj2仍是强引用
# 2. 弱引用示例
print("\n=== 弱引用示例 ===")
strong_obj = Data() # 创建一个强引用对象
print(f"创建Data对象")
weak_ref = weakref.ref(strong_obj) # 创建弱引用
print(f"创建弱引用后,引用计数: {sys.getrefcount(strong_obj) - 1}") # 引用计数仍为1!
# 通过弱引用访问对象(对象还活着)
print(f"通过弱引用访问: {weak_ref()}") # 输出类似: <__main__.Data object at 0x...>
del strong_obj # 删除**最后一个强引用**
print("删除最后一个强引用后...")
# 对象立即被回收(输出: Data 对象被回收了!)
# 再次通过弱引用访问
print(f"对象回收后,弱引用返回: {weak_ref()}") # 输出: None
输出结果:
=== 强引用示例 === 创建后引用计数: 1 赋值后引用计数: 2 删除obj1后引用计数: 1 === 弱引用示例 === 创建Data对象 创建弱引用后,引用计数: 1 通过弱引用访问: <__main__.Data object at 0x...> 删除最后一个强引用后... Data 对象被回收了! 对象回收后,弱引用返回: None
