Python WeakValueDictionary保留对不再具有强引用的对象的引用

Python WeakValueDictionary保留对不再具有强引用的对象的引用,python,mapping,python-2.7,weak-references,Python,Mapping,Python 2.7,Weak References,在执行脚本(而不是交互式解释器)时,它的行为也与预期一致: 如果您只是在交互式shell中尝试过这一点,我相信这与垃圾收集在该接口下的工作方式和全局范围操作有关 从脚本中尝试以下操作: foo.py from weakref import WeakValueDictionary class Foo(object): pass foo = Foo() db = WeakValueDictionary() db['foo-id'] = foo del foo print str(dict(f

在执行脚本(而不是交互式解释器)时,它的行为也与预期一致:


如果您只是在交互式shell中尝试过这一点,我相信这与垃圾收集在该接口下的工作方式和全局范围操作有关

从脚本中尝试以下操作:

foo.py

from weakref import WeakValueDictionary
class Foo(object):
    pass
foo = Foo()
db = WeakValueDictionary()
db['foo-id'] = foo
del foo
print str(dict(foo))
# prints {}
然后

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':}
{}
现在,从交互式python shell中尝试此操作,将操作移动到函数范围下:

$ python foo.py

{'f': <__main__.Foo object at 0x101f496d0>}
{}
从weakref导入WeakValue字典
类Foo(对象):
通过
f=Foo()
d=弱值字典()
d['f']=f
def main():
全局f
打印命令(d)
德尔夫
打印命令(d)
main()
#{'f':}
#{}

WeakValueDictionary
不保证在没有正常引用时删除条目。它所保证的是在适当的时候不会阻止垃圾收集——您的对象是可垃圾收集的,而不是垃圾收集的。当垃圾收集发生时,该条目将消失。

在Python交互式Shell中,无论您声明什么变量,都不会自动进行垃圾收集,因为
\uuuuuuu main\uuuuu
中的作用域尚未结束。Python中的垃圾收集基于引用计数,在您显式执行该操作或脱离当前作用域之前,它不会被收集

在同一个shell中,如果在函数内部实现
WeakRef
逻辑,您将看到预期的结果,因为在完成函数后,控件超出范围,对象被垃圾收集


这就是为什么@jdi with function的示例向您显示了您想要的内容。

我还尝试在交互式解释器中导入
gc
,并在
del
ing
foo
之后调用
gc.collect()
,从而消除了弱引用。显然,交互式解释器不会立即收集垃圾。如果没有一个科学的答案,我会简单地说,交互式shell并不是实现可实现行为的最佳案例。它非常适合测试,但不能被一个简单的可执行脚本打败。
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>}
{}
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>}
#{}