Django docs在这个主题上说这个:
另请注意,Django存储信号 处理程序作为弱引用 默认,所以如果你的处理程序是本地的 功能,可能是垃圾收集。 为防止这种情况,请在传递weak = False时 你调用信号的connect()。
我无法找到为什么这是默认值的任何理由,我不明白为什么你会希望你明确注册的信号隐式消失。那么弱引用的用例是什么?为什么它是默认值?
我意识到在99%的情况下这两种方式都没关系,但显然我在这里有一些不明白的东西,而且我想知道是否有任何“陷阱”潜伏在某一天可能会让我受伤。
答案 0 :(得分:11)
信号处理程序存储为弱引用,以避免它们引用的对象不被垃圾收集(例如在显式删除信号处理程序之后),只是因为信号仍在飞来飞去。
答案 1 :(得分:6)
绑定方法保留对它们所属对象的引用(否则,它们无法填充self
,参见Python documentation)。请考虑以下代码:
import gc
class SomeLargeObject(object):
def on_foo(self): pass
slo = SomeLargeObject()
callbacks = [slo.on_foo]
print [o for o in gc.get_objects() if isinstance(o, SomeLargeObject)]
del slo
print [o for o in gc.get_objects() if isinstance(o, SomeLargeObject)]
callbacks = []
print [o for o in gc.get_objects() if isinstance(o, SomeLargeObject)]
输出:
[<__main__.SomeLargeObject object at 0x15001d0>]
[<__main__.SomeLargeObject object at 0x15001d0>]
[]
在回调中保留weakrefs时要知道的一件重要事情是你不能直接弱化绑定方法,因为它们总是在运行中创建:
>>> class SomeLargeObject(object):
... def on_foo(self): pass
>>> import weakref
>>> def report(o):
... print "about to collect"
>>> slo = SomeLargeObject()
>>> #second argument: function that is called when weakref'ed object is finalized
>>> weakref.proxy(slo.on_foo, report)
about to collect
<weakproxy at 0x7f9abd3be208 to NoneType at 0x72ecc0>