根据 Weakref 模块的文档:
在下文中,术语所指对象是指被弱引用引用的对象。
对对象的弱引用不足以使对象保持活动状态:当对所指对象的唯一剩余引用是弱引用时,垃圾收集可以自由地销毁所指对象并将其内存用于其他用途。
MyCallbackA 发生的事情是您在 A 的实例中持有对它的引用,这要归功于 -
self.MyCallbackA = MyCallbackA
现在,您的代码中没有对绑定方法 MyCallbackB 的引用。它仅作为未绑定方法保存在 a.__class__.__dict__ 中。基本上,当您执行 self.methodName 时,会创建一个绑定方法(并返回给您)。(AFAIK,绑定方法的工作方式类似于使用描述符(只读)的属性:至少对于新样式类。我敢肯定,旧样式类会发生类似的事情,即没有描述符。我将其留给更有经验的人来验证有关旧样式类的声明。)因此, self.MyCallbackB 在创建弱引用后立即死亡,因为没有对它的强引用!
我的结论基于:-
import weakref
#Trace is called when the object is deleted! - see weakref docs.
def trace(x):
print "Del MycallbackB"
class A(object):
def __init__(self):
def MyCallbackA():
print 'MyCallbackA'
self.MyCallbackA = MyCallbackA
self._testA = weakref.proxy(self.MyCallbackA)
print "Create MyCallbackB"
# To fix it, do -
# self.MyCallbackB = self.MyCallBackB
# The name on the LHS could be anything, even foo!
self._testB = weakref.proxy(self.MyCallbackB, trace)
print "Done playing with MyCallbackB"
def MyCallbackB(self):
print 'MyCallbackB'
def test_a(self):
self._testA()
def test_b(self):
self._testB()
if __name__ == '__main__':
a = A()
#print a.__class__.__dict__["MyCallbackB"]
a.test_a()
输出
Create MyCallbackB
Del MycallbackB
Done play with MyCallbackB
MyCallbackA
注意:
我尝试为旧样式类验证这一点。原来“print a.test_a.__get__”输出——
<method-wrapper '__get__' of instancemethod object at 0xb7d7ffcc>
适用于新旧风格的课程。所以它可能不是真正的描述符,只是类似描述符的东西。无论如何,重点是当你通过 self 访问一个实例方法时会创建一个绑定方法对象,除非你保持对它的强引用,否则它将被删除。