弱引用
正是由於有引用,對象纔會在內存中存在。
當對象的引用數量歸零後,垃圾回收程序會把對象銷燬。
可是,有時須要引用對象,而不讓對象存在的時間超過所需時間。
這常常用在緩存中。
弱引用不會增長對象的引用數量。
引用的目標對象稱爲所指對象(referent)。
所以咱們說,弱引用不會妨礙所指對象被看成垃圾回收。
弱引用在緩存應用中頗有用,由於咱們不想僅由於被緩存引用着而始終保存緩存對象。
若是對象存在,調用弱引用能夠獲取對象;不然返回 None。
弱引用是可調用的對象,返回的是被引用的對象;若是所指對象不存在了,返回 None。
WeakValueDictionary簡介
WeakValueDictionary 類實現的是一種可變映射,裏面的值是對象的弱引用。
被引用的對象在程序中的其餘地方被看成垃圾回收後,對應的鍵會自動從 WeakValueDictionary 中刪除。
所以,WeakValueDictionary 常常用於緩存。
臨時變量引用了對象,這可能會致使該變量的存在時間比預期長。
一般,這對局部變量來講不是問題,由於它們在函數返回時會被銷燬。
可是全局變量,除非顯式刪除,不然不會消失。
weakref 模塊還提供了 WeakSet 類,按照文檔的說明,這個類的做用很簡單:「保存元素弱引用的集合類。元素沒有強引用時,集合會把它刪除。
」若是一個類須要知道全部實例,一種好的方案是建立一個WeakSet 類型的類屬性,保存實例的引用。
若是使用常規的 set,實例永遠不會被垃圾回收,由於類中有實例的強引用,而類存在的時間與Python 進程同樣長,除非顯式刪除類。
弱引用的侷限
不是每一個 Python 對象均可以做爲弱引用的目標(或稱所指對象)。
基本的 list 和 dict 實例不能做爲所指對象,可是它們的子類能夠輕鬆地解決這個問題:
class MyList(list):
"""list的子類,實例能夠做爲弱引用的目標"""
a_list = MyList(range(10))
# a_list能夠做爲弱引用的目標
wref_to_a_list = weakref.ref(a_list)
set 實例能夠做爲所指對象。用戶定義的類型也沒問題。
可是,int 和 tuple 實例不能做爲弱引用的目標,甚至它們的子類也不行。