保持参考超出范围对象的方法

时间:2016-09-09 22:36:58

标签: python python-2.7 python-3.x garbage-collection

class Foo:
    def __init__(self, _label):
        self.label = _label
    def display(self):
        print(str(self.label))
    def get_display(self):
        return self.display

display_test = Foo(1).get_display()
display_test()
def inner_scope():
    global display_test
    display_test = Foo(2).get_display()
inner_scope()
display_test()

在Python 2.7中,上面的块打印1后跟2,这并不令人惊讶。但是,我感到好奇的是,Foo(1)Foo(2)生成的对象会发生什么 - 看起来好像它们从那时起没有被垃圾收集{{1}调用,但这是否意味着display_test引用display_test,防止它被垃圾收集?在调用Foo(2)之前,我是否幸运地认为对象没有被垃圾收集?这在display_test

中有所不同吗?

2 个答案:

答案 0 :(得分:1)

你的问题有点不清楚。这句话:“看起来好像他们在调用display_test时没有被垃圾收集”这表明有些混乱。事实上,display_test被调用两次 - 一次绑定到Foo(1)的实例方法时,再次绑定到Foo(2)的实例方法时。在调用inner_scope之前,display_test保存对Foo(1)的引用,因此它不会被GC。在调用inner_scope之后,不再有任何对Foo(1)的引用,因此它已准备好用于GC。但是display_test现在持有对Foo(2)的引用,所以 不会得到GC。所以“他们” - 对象Foo(1)和Foo(2) - 没有得到GC,而是一次一个,每个对象的GC独立取决于是否有任何实时引用。

不要担心Python垃圾收集器。它工作得很漂亮。

答案 1 :(得分:0)

在Python 2中,display_test包含对instancemethod对象的引用,其中一个属性为im_self,即方法绑定的实例。

在Python 3中,display_test包含对method对象的引用,其中一个属性为__self__(Python 3等效于im_self)。