在【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': , 'name': '1'}
所以,即使手動調用了 a = None, b = None, c = None,對象也不會被刪除
Garbage:[,
,
,
{'name': 'one', 'other': },
{'name': 'two', 'other': },
{'name': 'three', 'other': }]
而弱引用是指「引用一個對象,但並不增加被引用對象的指針計數」
可以通過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對象~
更多技巧請《轉發 + 關注》哦!