我想了解的Python weakref
模塊及其使用情況保留GC.Collect的後值(),所以我有以下設置:的Python WeakValueDictionary在IPython中
import gc, weakref
class obj(object):
def __init__(self, val=None):
self._s = "Sample" if not val else " ".join(["Sample:", str(val)])
def sample(self):
return self._s
ol = [obj(x) for x in range(1,4)]
o1 = obj(1)
o2 = obj(2)
o3 = obj(3)
wdict1 = weakref.WeakValueDictionary({k:ol[k-1] for k in range(1,4)})
wdict2 = weakref.WeakValueDictionary()
wdict2[1] = o1
wdict2[2] = o2
wdict2[3] = o3
運行我的測試中我可以明確後看,WeakValueDictionary
莫名其妙地保留了所有的值,即使我明確地稱爲gc.collect()
。據我的理解,如下面的answer所解釋的,調用gc.collect()
應該刪除所有弱引用的值。
In [2]: wdict1.items()
Out[2]:
[(1, <__main__.obj at 0x7fea09c0be90>),
(2, <__main__.obj at 0x7fea09c0bf10>),
(3, <__main__.obj at 0x7fea09c0bf50>)]
In [3]: wdict2.items()
Out[3]:
[(1, <__main__.obj at 0x7fea09c51790>),
(2, <__main__.obj at 0x7fea09c0bed0>),
(3, <__main__.obj at 0x7fea09c0bf90>)]
In [4]: del ol[0]
In [5]: del o1
In [6]: gc.collect()
Out[6]: 64
In [7]: wdict1.items()
Out[7]:
[(1, <__main__.obj at 0x7fea09c0be90>),
(2, <__main__.obj at 0x7fea09c0bf10>),
(3, <__main__.obj at 0x7fea09c0bf50>)]
In [8]: wdict2.items()
Out[8]:
[(1, <__main__.obj at 0x7fea09c51790>),
(2, <__main__.obj at 0x7fea09c0bed0>),
(3, <__main__.obj at 0x7fea09c0bf90>)]
In [9]: del ol[0]
In [10]: del o2
In [11]: gc.collect()
Out[11]: 0
In [12]: wdict1.items()
Out[12]:
[(1, <__main__.obj at 0x7fea09c0be90>),
(2, <__main__.obj at 0x7fea09c0bf10>),
(3, <__main__.obj at 0x7fea09c0bf50>)]
In [13]: wdict2.items()
Out[13]:
[(1, <__main__.obj at 0x7fea09c51790>),
(2, <__main__.obj at 0x7fea09c0bed0>),
(3, <__main__.obj at 0x7fea09c0bf90>)]
In [14]: weakref.getweakrefs(ol[0])
Out[14]: [<weakref at 0x7fea0ab05470; to 'obj' at 0x7fea09c0bf50>]
In [15]: weakref.getweakrefs(o3)
Out[15]: [<weakref at 0x7fea09c060b0; to 'obj' at 0x7fea09c0bf90>]
In [16]: wdict1[1].sample()
Out[16]: 'Sample: 1'
In [17]: wdict2[2].sample()
Out[17]: 'Sample: 2'
我的代碼出了什麼問題,爲什麼所有弱引用的值都保留了?
它對我來說工作正常,你確定你沒有繼續引用'o1'或任何來自'ol'的任何其他名稱的對象嗎?重新啓動python會話後嘗試相同 –
我使用'ipython 2.3.0'。所以我打開新的控制檯和'%cpaste' my * setup *代碼,然後複製/粘貼我的測試代碼 - 輸出結果在上面。沒有其他變量也沒有加載模塊。 –