>>> from weakref import WeakValueDictionary
>>> class Foo(object):
... pass
>>> foo = Foo()
>>> db = WeakValueDictionary()
>>> db['foo-id'] = foo
>>> del foo
>>> dict(db)
{'foo-id': <__main__.Foo object at 0x4dd946c>}
为什么它显示此而不是空字典?请注意,此代码生成我期望的结果:
>>> db2 = WeakValueDictionary()
>>> db2['disposable-id'] = Foo()
>>> dict(db2)
{}
执行脚本(而不是交互式解释器)时,它的行为也符合预期:
from weakref import WeakValueDictionary
class Foo(object):
pass
foo = Foo()
db = WeakValueDictionary()
db['foo-id'] = foo
del foo
print str(dict(foo))
# prints {}
答案 0 :(得分:6)
WeakValueDictionary
不保证在没有正常引用时将删除条目。它保证的是它不会在适当的时候阻止垃圾收集 - 你的对象是垃圾收集,而不是垃圾收集。垃圾收集发生时,该条目将消失。
答案 1 :(得分:3)
如果你只是在交互式shell中尝试这个,我相信它与垃圾收集在该接口和全局范围操作下的工作方式有关。
从脚本中试试这个:
<强> foo.py 强>
from weakref import WeakValueDictionary
class Foo(object):
pass
f = Foo()
d = WeakValueDictionary()
d['f'] = f
print dict(d)
del f
print dict(d)
然后......
$ python foo.py
{'f': <__main__.Foo object at 0x101f496d0>}
{}
现在,从交互式python shell中尝试这个,在函数范围内移动操作:
from weakref import WeakValueDictionary
class Foo(object):
pass
f = Foo()
d = WeakValueDictionary()
d['f'] = f
def main():
global f
print dict(d)
del f
print dict(d)
main()
#{'f': <__main__.Foo object at 0x100479f10>}
#{}
答案 2 :(得分:1)
在Python Interactive Shell中,无论您声明什么变量,都不会自动收集垃圾,因为__main__
中的范围尚未结束。 Python中的垃圾收集基于引用计数,在您明确执行或取消当前范围之前,它不会被收集。
在同一个shell中,如果在函数内部实现WeakRef
逻辑,您将看到预期的结果,因为在完成函数时,控件超出范围并且垃圾收集对象。
这就是为什么@jdi带有功能的例子正在向你展示你想要的东西。