在【python 標準庫】中看到的一段代碼,非常有協助:
def all_nodes(self): yield self n = self.other while n and n.name != self.name: yield n n = n.other if n is self: yield n return
首尾的2處yield均只返回一次,作為循環圖表的起點、終點,而n作為圖可能的節點,每次在next調用中均返回next節點
利用這個迭代器,就可以輕鬆列印出圖的結構:
def __str__(self): return '->'.join((n.name for n in self.all_nodes()))
Graph:one->two->three->one
實現一個圖結構需要利用python裡面的弱引用,
我們先看一下標準的向圖結構中增加下一節點的代碼:
def set_next(self, other): print '%s.next %r' % ( self.name, other) self.other = other
這樣綁定後,在屬性欄位中,增加一個對於下一節點的引用
c.__dict__{'other': <Graph at 0xb7507e4c name=2>, 'name': '1'}
所以,即使手動調用了 a = None, b = None, c = None,對象也不會被刪除
Garbage:[<Graph at 0xb739856c name=one>, <Graph at 0xb739866c name=two>, <Graph at 0xb739868c name=three>, {'name': 'one', 'other': <Graph at 0xb739866c name=two>}, {'name': 'two', 'other': <Graph at 0xb739868c name=three>}, {'name': 'three', 'other': <Graph at 0xb739856c name=one>}]
而弱引用是指“引用一個對象,但並不增加被引用對象的指標計數”
可以通過c = weekref.ref(k,func)
來指定引用的對象及對象刪除後的動作func
調用時,使用c() 來引用k
但是在上個例子裡面,我們需要一個“代理對象”來代理這個被引用的對象,從而使set_next 函數對於變數other可以同正常變數一樣使用
def set_next(self, other): if other is not None: if self in other.all_nodes(): other = weakref.proxy(other) super(WeakGraph, self).set_next(other) return
從而避免了通過other()來引用一個other對象~