2012-03-28 106 views
32

我一直在試圖理解python弱引用列表/字典的工作方式,並且一直在閱讀它的文檔,但是我似乎無法弄清楚它們是如何工作的以及它們可以用於什麼。任何人都可以給我一個他們做什麼的基本例子/他們如何工作的解釋?非常感謝。python中的弱引用

(EDIT)使用托馬斯的代碼,當我代替OBJ爲[1,2,3]它拋出:

Traceback (most recent call last): 
File "C:/Users/nonya/Desktop/test.py", line 9, in <module> 
r = weakref.ref(obj) 
TypeError: cannot create weak reference to 'list' object 

回答

41

理論

引用計數通常可以作爲這樣的:每次創建一個對象的參考時間,則增加一個,而當你刪除一個參考,它是由一個下降。

弱引用允許您創建對不會增加引用計數的對象的引用。

引用計數由python的垃圾收集器在運行時使用:引用計數爲0的任何對象都將被垃圾收集。

對於昂貴的對象或避免循環引用(儘管垃圾回收器通常自行完成),您將使用弱引用。

使用

這裏有一個工作示例演示它們的用法:

import weakref 
import gc 

class MyObject(object): 
    def my_method(self): 
     print 'my_method was called!' 

obj = MyObject() 
r = weakref.ref(obj) 

gc.collect() 
assert r() is obj #r() allows you to access the object referenced: it's there. 

obj = 1 #Let's change what obj references to 
gc.collect() 
assert r() is None #There is no object left: it was gc'ed. 
+0

它是如何在列表/字典上工作的,儘管這是類/函數的一個很好的例子。 :) – 2012-03-28 13:22:42

+0

請你看看我的編輯。當代替列表或字典時,會拋出該錯誤。 – 2012-03-28 14:04:40

+0

我的不好,我完全忽略了這一點,你確實無法爲'list'或其他複合類型創建weakref--你確切的目的是什麼? – 2012-03-28 14:11:01

9

的一點是,他們允許引用保留到對象,而不防止它們被垃圾收集。

您希望這樣做的兩個主要原因是您自己進行定期資源管理的地方,例如,關閉文件,但由於這些傳遞之間的時間可能很長,垃圾收集器可能會爲你做;或者創建對象的位置,追蹤它在程序中的位置可能相對昂貴,但您仍然想要處理實際存在的實例。

第二種情況可能是比較常見的 - 當您拿着例如手錶時,它是合適的。要通知的對象列表,並且您不希望通知系統阻止垃圾回收。

+0

也許有3個原因?第三次突破循環引用。 – dashesy 2015-09-15 01:08:39

+1

@dashesy是否正確。弱引用最常見的(可引用的,唯一的safe_)用例是明確地中斷引用循環。儘管Python垃圾收集器無論如何都可以並且最終會破壞這樣的循環,但是首先防止這種循環形成的空間和時間密集程度要低得多。所有其他使用弱引用的東西最多都是脆弱的,並且絕對應該被一點恐懼和尊重所對待。 – 2016-03-11 02:39:48

12

只是想指出的是,weakref.ref不適用於內置列表工作,因爲存在的__slots__沒有__weakref__名單。 例如,下面的代碼定義了一個支持weakref的列表容器。

import weakref 

class weaklist(list): 
    __slots__ = '__weakref__', 

l = weaklist() 
r = weakref.ref(l)