每次继承抽象类时,我都可以运行代码吗?



我需要连接从抽象类继承的所有类的Django信号。是否有像__on_inherit__这样的魔术python方法,它可以让我每次继承我的抽象类时运行信号连接代码?

更新:为了澄清,我需要在课堂评估上每类运行一次代码,而不是每个实例/对象一次。

是的,确实有[__init_subclass__] [1]钩,每次都会触发类。

将第一个参数 cls称为 new sub类(不是原始父类(。正如文档中所述的那样,您甚至可以将任意论据传递给子类别的钩子。

希望这对您有帮助。

编辑:通过Python版本3.6中的PEP 487 [2]添加了这一点。在较早的Python版本中,此方法不称为。

[1] https://docs.python.org/3/reference/datamodel.html#object。 init_s> init_subclass

[2] https://www.python.org/dev/peps/pep-0487/

我们可以为此实现解决方案。首先,我们可以生成一个抽象模型的子类集,例如使用此解决方案:

def get_descendants(klass):
    gen = { klass }
    desc = set()
    while gen:
        gen = { skls for kls in gen for skls in kls.__subclasses__() }
        desc.update(gen)
    return desc

接下来我们可以迭代此事,每次调用一个函数,例如:

for subclass in get_descendants(AbstractModel):
    # ... do something with that subclass
    pass

其中 AbstactModel 是要得出子类的抽象模型。

您应该在加载应用程序时触发对此的评估,例如,在AppConfig ready() 方法[django-doc]中。

这非常罕见,尤其是对于模型以后进行新的子类。对于那些非常罕见的模型,无论如何都不是一个好主意,因为当您想进行迁移时,这可能不起作用。

示例:向每个子类添加信号

我们可以通过首先定义信号处理程序来为 AbstractModel 的每个子类添加信号:

def test_signal(sender, instance, **kwargs):
    print('{} is saved'.format(instance))

,然后我们可以将其与每个子类连接:

from django.db.models.signals import post_save
for subclass in get_descendants(AbstractModel):
    post_save.connect(test_signal, sender=subclass)

对于Python> = 3.6,Terseus已经提到的__init__subclass__ OK。

对于较旧的python方面,挂接类创建的规范方式(我的意思是"创建新类对象"(是使用自定义元口和覆盖__new____init__方法(这是广泛记录的,所以我赢了't port示例(。

相关内容

最新更新