2013-06-05 48 views
0

我需要創建一個容器,可以訪問其子,但也可以訪問其父。 這裏是我怎麼想這樣做一個簡單的例子:訪問python容器的父對象

import numpy as np 
import gc 


class Node(object): 

    def __init__(self, name): 
     self.parent = None 
     self.child = [] 
     self.name = name 
     self.mem_tracer = np.ones(10 ** 6) 

    def append(self, obj): 
     assert(isinstance(obj, Node)) 
     self.child.append(obj) 
     obj.parent = self 

但是,與我有記憶問題,當我試圖刪除一個節點(注意屬性mem_tracer只是在這裏能以查看是否該對象已經從內存中刪除或不)

此代碼顯示了問題(在每個行中的存儲器狀態給出):

print 'start'     # 16.96Mb 

a = Node('0')     # 24.79Mb 

a.append(Node('0/0'))   # 32.61Mb 
a.append(Node('0/1'))   # 40.42Mb 

a.child[0].append(Node('0/0/0')) # 48.24Mb 
a.child[0].append(Node('0/0/1')) # 56.06Mb 

a.child[1].append(Node('0/1/0')) # 63.87Mb 
a.child[1].append(Node('0/1/1')) # 71.69Mb 

del a.child[0]     # 71.69Mb 

gc.collect()      # 48.24Mb 

垃圾收集器是不能夠收集刪除的對象作爲參考依然存在在它的孩子中(雖然他們沒有被引用到任何地方)。 我們可以在最後一行看到,明確地致電gc.collect解決了這個問題,但我寧願放棄它,因爲它非常耗時!

那麼有沒有其他的方式來訪問父容器比存儲到一個屬性? 在此先感謝。

+1

您可以使用'weakref.ref'來存儲對父項的引用。這還不足以保持垃圾收集器中的對象活着,但如果垃圾收集器沒有收集到垃圾回收器,則足以讓您返回對象的引用。 (但是我還沒有想過所有的含義......例如,如果你的對象對於GC來說是安全的,例如,如果你僅僅關注對鏈表頭部的引用)。 – mgilson

+0

非常感謝! ''weakref''解決了一切!沒有內存泄漏了! –

回答

0

你有兩個選擇:

  • 手動刪除obj.parent
  • 使用weakref保持一個僞參考父。

有關weakref的更多信息,請參閱the docs