Python中的弱引用

weakref模块具有的方法

class weakref.ref(object[, callback])
创建一个弱引用对象,object是被引用的对象,callback是回调函数(当被引用对象被删除时的,会调用改函数)。

weakref.proxy(object[, callback])
创建一个用弱引用实现的代理对象,参数同上。

weakref.getweakrefcount(object)
获取对象object关联的弱引用对象数

weakref.getweakrefs(object)
获取object关联的弱引用对象列表

class weakref.WeakKeyDictionary([dict])
创建key为弱引用对象的字典

class weakref.WeakValueDictionary([dict])
创建value为弱引用对象的字典

class weakref.WeakSet([elements])
创建成员为弱引用对象的集合对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
### 创建弱引用
>>> from socket import *
>>> import weakref
>>> s=socket(AF_INET,SOCK_STREAM)
>>> ref=weakref.ref(s)
>>> s
<socket._socketobject instance at 007B4A94>
>>> ref
<weakref at 0x81195c; to 'instance' at 0x7b4a94>
>>> ref() #调用它来访问被引用的对象
<socket.socketobject instance at 007B4A94>
一旦没有了对这个对象的其它的引用,调用弱引用将返回None,因为Python已经销毁了这个对象。 注意:大部分的对象不能通过弱引用来访问。
### 创建代理对象
>>> from socket import*
>>> import weakref
>>> s=socket(AF_INET,SOCK_STREAM)
>>> ref=weakref.proxy(s)
>>> s
<socket._socketobject instance at 007E4874>
>>> ref
<socket._socketobject instance at 007E4874>
>>> ref.close() #对象的方法同样工作

例子

创建缓存实例
当创建类实例时,我们想反悔一个缓存引用,让其指向上一个用同样参数(如果有的话)创建出的类实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import sys
class Spam:
def __init__(self, name):
self.name = name
import weakref
_spam_cache = weakref.WeakValueDictionary()
def get_spam(name):
if name not in _spam_cache:
s = Spam(name)
_spam_cache[name] = s
else:
s = _spam_cache[name]
return s
if __name__ == '__main__':
a = get_spam('foo')
b = get_spam('bar')
print(sys.getrefcount(a))
print('a is b:', a is b)
c = get_spam('foo')
print(sys.getrefcount(a))
print('a is c:', a is c)
# 2
# a is b: False
# 3
# a is c: True
print(list(_spam_cache))
del a
print(list(_spam_cache))
del c
print(list(_spam_cache))
# ['foo', 'bar']
# ['foo', 'bar']
# ['bar']

封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import weakref
class CachedSpamManager:
def __init__(self):
self._cache = weakref.WeakValueDictionary()
def get_spam(self, name):
if name not in self._cache:
s = Spam(name)
self._cache[name] = s
else:
s = self._cache[name]
return s
class Spam:
def __init__(self, name):
self.name = name
Spam.manager = CachedSpamManager()
def get_spam(name):
return Spam.manager.get_spam(name)
if __name__ == '__main__':
a = get_spam('foo')
b = get_spam('bar')
print('a is b:', a is b)
c = get_spam('foo')
print('a is c:', a is c)
文章目录
  1. 1. weakref模块具有的方法
  2. 2. 例子
  3. 3. 封装
|