import sys sys.getrefcount()#接受一个参数对象但是引用计数有一个明显的缺点就是无法解决循环引用的问题即 a 引用 b, b 引用 a,导致其引用计数永远不为 0,这样就会导致内存无法释放也浪费了系统内存,从而造成内存泄露的问题。为了避免这个问题 Python 提供了 weakref 即弱引用。它的效果是:当对一个对象创建了弱引用时,对象的引用计数不会增加。示例如下所示:
In [1]: import sys,weakref In [2]: class A: ...: def hello(self): ...: return "c语言中文网" ...: In [3]: a=A() In [4]: sys.getrefcount(a) Out[4]: 4 In [5]: ref=weakref.ref(a) In [6]: sys.getrefcount(a) Out[6]: 4weakref 的 ref 方法用于创建弱引用对象,它的返回值是引用指向的对象。函数定义如下:
weakref.ref(object[callback,])其中 object 即为被引用的对象,而 callback 是一个可选的回调函数。当引用的对象被删除的时候,回调函数就会被执行调用。通过 weakref.ref 创建的弱引用,在使用时需要使用 ref() 去获取 object:
In [1]: ref().hello() Out[2]: 'c语言中文网'weakref 提供了 finalize 来定义引用对象被删除时执行的清理函数,它的定义如下:
finaiize(object,func,*args,**kwargs)其中,object 是引用的对象;func 是清理函数,obj 被删除时自动调用;*args 和 **kwargs 将会作为参数传递给清理函数。所以使用它的时候需要预先定义清理函数,示例如下:
In [9]: def func(obj): ...: print("%s被删除"%obj) ...: In [10]: weakref.finalize(a,func,str(hex(id(a)))) Out[10]: <finalize object at 0x508bd98; for 'A' at 0x85a7930> In [11]: del a 0x85a7930被删除这里还有一种特殊的情况即引用对象是对象实例的方法,此时不可以直接使用 weakref.ref 去创建弱引用,而是使用 weakref.WeakMethod(),示例如下:
In [14]: a=A() In [15]: ref=weakref.WeakMethod(a.hello)#引用对象a的hello方法 In [16]: ref()() Out[16]: 'c语言中文网' In [17]: ref() Out[17]: <bound method A.hello of <__main__.A object at 0x05B64F30>>因为弱引用不会改变对象的引用计数,所以,Django 信号机制采用弱引用的方式对信号回调函数进行引用,以此来避免内存泄露的问题。
Copyright © 广州京杭网络科技有限公司 2005-2025 版权所有 粤ICP备16019765号
广州京杭网络科技有限公司 版权所有