Python内存管理
1.del与垃圾回收:del语句删除名称,而不是对象。仅当变量保存的是对象的最后一个引用,或者无法得到对象时,del命令才会导致对象被当作垃圾回收。
class A(list): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) print("create", id(self)) def __del__(self): print("del", id(self)) a = A([10, 20]) b = A([a, 30]) a[-1] = b print(a, b) del b del a print("exit...") """ create 2418962187912 create 2418962186632 [10, [[...], 30]] [[10, [...]], 30] exit... del 2418962187912 del 2418962186632 """ a = A([10, 20]) b = A([a, 30]) a[-1] = b print(a, b) del b del a[-1] print("exit...") """ create 2153516090936 create 2153516089656 [10, [[...], 30]] [[10, [...]], 30] del 2153516089656 exit... del 2153516090936 """
2.如果两个对象相互引用,当它们的引用只存在二者之间时,垃圾回收程序会判定它们都无法获取,因而将它们都销毁。
3.关于弱引用:不要直接使用 weakref.ref(obj) 创建对象,应使用 weakref.finalize(obj, func) 或 WeakValueDictionary,WeakKeyDictionary,WeakSet 代替。
weakref.finalize(obj, func) 弱引用对象 obj,当obj被当作垃圾回收时, 调用函数 func。
WeakValueDictionary经常用于缓存,它实现了一个可变映射,里面的值是对象的弱引用,当被引用的对象在程序中的其他地方被当作垃圾回收后,对应的键会自动从WeakValueDictionary中删除;
WeakKeyDictionary 与之不同的地方在于,其键是弱引用,WeakKeyDictionary可以为应用中其他部分拥有的对象附加数据,这样就无需要为对象添加属性。
WeakSet类保存元素的弱引用的集合类,元素没有强引用时,集合会把它删除。
需要注意的是,不是每个类型的对象都能作为弱引用的目标,其中 int 与 tuple 及其子类都不可以, list 与 dict 实例不可以,但其子类可以。
import weakref a = {1, 2, 3} def bye(): print("Byte! Cruel world!") wref = weakref.finalize(a, bye) print(wref.alive) del a print(wref.alive) print("exit...") # True Byte! Cruel world! False exit...
class Fruit(): def __init__(self, kind): self.kind = kind def __repr__(self): return "Fruit(%r)" % self.kind fruits = [Fruit("apple"), Fruit("banana"), Fruit("Peach")] stock = weakref.WeakValueDictionary() for fruit in fruits: stock[fruit.kind] = fruit del fruits del fruit print(list(stock.keys())) # [] print(list(stock.values())) # []
class Fruit(): def __init__(self, kind): self.kind = kind def __repr__(self): return "Fruit(%r)" % self.kind fruits = [Fruit("apple"), Fruit("banana"), Fruit("Peach")] stock = weakref.WeakKeyDictionary() print(fruits) for fruit in fruits: stock[fruit] = fruit.kind del fruits del fruit print(list(stock.keys())) # [] print(list(stock.values())) # []
代码养活自己

浙公网安备 33010602011771号