python弱引用

和许多其它的高级语言一样,Python使用了垃圾回收器来自动销毁那些不再使用的对象。每个对象都有一个引用计数,当这个引用计数为0时Python能够安全地销毁这个对象。使用weakref模块,你可以创建到对象的弱引用,Python在对象的引用计数为0或只存在对象的弱引用时将回收这个对象。一、 创建弱引用你可以通过调用weakref模块的ref(obj[,callback])来创建一个弱引用,obj是你想弱引用的对象,callback是一个可选的函数,当因没有引用导致Python要销毁这个对象时调用。回调函数callback要求单个参数(弱引用的对象)。一旦你有了一个对象的弱引用,你就能通过调用弱引用来获取被弱引用的对象。下面的例子创建了一个对socket对象的弱引用:
from socket import *
import weakref
s=socket(AF_INET,SOCK_STREAM)
ref=weakref.ref(s)
print(s)#<socket.socket fd=484, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0>


print(ref)#<weakref at 0x00000290436C5818; to 'socket' at 0x000002904393CC78>

print(ref() )   #调用它来访问被引用的对象  <socket.socket fd=484, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0>


一旦没有了对这个对象的其它的引用,调用弱引用将返回None,因为Python已经销毁了这个对象。 注意:大部分的对象不能通过弱引用来访问。weakref模块中的getweakrefcount(obj)和getweakrefs(obj)分别返回弱引用数和关于所给对象的引用列表。弱引用对于创建对象(这些对象很费资源)的缓存是有用的。二、创建代理对象代理对象是弱引用对象,它们的行为就像它们所引用的对象,这就便于你不必首先调用弱引用来访问背后的对象。通过weakref模块的proxy(obj[,callback])函数来创建代理对象。使用代理对象就如同使用对象本身一样:
from socket import*
import weakref
s=socket(AF_INET,SOCK_STREAM)
ref=weakref.proxy(s)
print(s)#<socket.socket fd=484, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0>

print(ref)#<socket.socket fd=484, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0>
ref.close() #对象的方法同样工作

callback参数的目的和ref函数相同。在Python删除了一个引用的对象之后,使用代理将会导致一个weakref.ReferenceError错误:

from socket import*
import weakref
s=socket(AF_INET,SOCK_STREAM)
ref=weakref.proxy(s)
print(s)#<socket.socket fd=464, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0>


print(ref)#<socket.socket fd=464, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0>
ref.close() #对象的方法同样工作


del s
print(ref)  # <socket.socket [closed] fd=-1, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0>


  

弱引用使用的机会不是很多,一般用来进行 cache 编程。我们可以使用 weakref.ref() 来创建一个弱引用。

import sys
import weakref
class Class1:
    def test(self):
        print("test...")
o=Class1()
print(sys.getrefcount(o))#2


r=weakref.ref(o)# 创建一个弱引用 2
print(sys.getrefcount(o))#引用计数并没有改变

print(r)# 弱引用所指向的对象信息 <weakref at 0x00000238109A9778; to 'Class1' at 0x000002381074B1D0>



o2=r()# 获取弱引用所指向的对象
print(o is o2) #True

print(sys.getrefcount(o))#3

o=None
o2=None
print(r)#当对象引用计数为零时,弱引用失效。<weakref at 0x00000238109A9778; dead>


weakref 还提供了一个 proxy():

import sys
import weakref
class Class1:
 def test(self):
 print "test"
 
def callback(self):
 print "callback"
 
o = Class1()
p = weakref.proxy(o, callback)
p.test()
o = None
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值