在【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物件~