python 圖 自身遍歷及弱引用使用

pythontab發表於2013-06-14

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


相關文章