为什么在没有弱= False的情况下删除Django信号?

时间:2015-04-23 11:02:59

标签: python django

更新 下面发布的代码非常好。我刚刚找到了我的问题的答案:我用另一个在该模块上使用相同名称的处理器覆盖了处理程序,因此weakref被删除了...其他人可以使用下面的代码根据Django文档正确地注册信号

在我的Django 1.8,Python 2.7.9中,我定义了一个永远不会被调用的信号。看起来由于某种原因它被垃圾收集。处理程序是在模块级别定义的,而不是在函数内部,所以我希望它只要程序运行就会保留在那里。连接信号时使用weak = False可以解决问题,但我想知道这种行为的具体情况。

这大致是我使用的代码:

#  myapp/apps.py

from django.apps import AppConfig

class MyAppConfig(AppConfig):

    name = 'myapp'

    def ready(self):
        import myapp.signals  
#  myapp/__init__.py

default_app_config = 'myapp.apps.MyAppConfig'
#  myapp/signals.py

from django.db.models.signals import post_delete
from django.dispatch import receiver
from otherapp.models import Model

@receiver(post_delete, sender=Model)  # weak=True
def post_delete_hype_callback(sender, **kwargs):
    # Do stuff here
    pass

Model上的post_delete信号永远不会被调用。我甚至无法在连接信号列表中看到它。在接收器装饰器上使用weak = False解决了这个问题。

从我的观点来看,接收器装饰器返回正在装饰的实际函数,因此它应该保持在模块级别并且永远不会被垃圾收集。我还检查了当应用程序调用就绪时(通过使用import myapp.signals)处理程序连接到信号。

我能想到的唯一合理的解释是,一旦MyAppConfig的ready()方法完成,signals.py模块就会收集垃圾,因为在任何地方都没有其它引用,但这不是行为我期待。

这似乎是根据Django文档连接信号的推荐方法,但似乎并不适用于我。

任何人都可以对这种行为有所了解吗?

1 个答案:

答案 0 :(得分:7)

我刚刚找到了我的问题的答案:代码完全正常,但我用一个不同的处理程序覆盖了函数,我在它下面定义了相同的名字...... -.- u这就是为什么那个处理程序是当weakrefs被使用时被垃圾收集。我将问题留在这里,以便其他人可以根据Django文档了解如何正确连接信号。

相关问题