代码改变世界

python weakref弱引用

2017-02-08 15:30  放作夥  阅读(2355)  评论(0编辑  收藏  举报

weakref号称可以解决循环引用gc和创建缓存。我困惑的是python的gc到底能不能解决循环引用的问题,有资料说python的gc是有别的辅助机制可以解决循环依赖,但是我又看见这样的代码。

# -*- coding:utf-8 -*-
import weakref
import gc
from pprint import pprint
 
 
class Graph(object):
    def __init__(self, name):
        self.name = name
        self.other = None
 
    def set_next(self, other):
        print "%s.set_next(%r)" % (self.name, other)
        self.other = other
 
    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
 
    def __str__(self):
        return "->".join(n.name for n in self.all_nodes())
 
    def __repr__(self):
        return "<%s at 0x%x name=%s>" % (self.__class__.__name__, id(self), self.name)
 
    def __del__(self):
        print "(Deleting %s)" % self.name
 
def collect_and_show_garbage():
    print "Collecting..."
    n = gc.collect()
    print "unreachable objects:", n
    print "garbage:",
    pprint(gc.garbage)
 
 
def demo(graph_factory):
    print "Set up graph:"
    one = graph_factory("one")
    two = graph_factory("two")
    three = graph_factory("three")
    one.set_next(two)
    two.set_next(three)
    three.set_next(one)
 
    print
    print "Graph:"
    print str(one)
    collect_and_show_garbage()
 
    print
    three = None
    two = None
    print "After 2 references removed"
    print str(one)
    collect_and_show_garbage()
 
    print
    print "removeing last reference"
    one = None
    collect_and_show_garbage()
 
 
gc.set_debug(gc.DEBUG_LEAK)
print "Setting up the cycle"
print 
demo(Graph)
print
print "breaking the cycle and cleaning up garbage"
print
gc.garbage[0].set_next(None)
while gc.garbage:
    del gc.garbage[0]
print collect_and_show_garbage()

这段代码试图说明python的gc并不那么智能