Python / Django:为什么在使用模块之前立即导入模块会阻止循环导入?

斯巴达克斯

在不同情况下,我已经遇到过几次此问题,但是我的设置如下:

我有两个Django模型文件。包含用户模型和用户可以用来注册课程的CouponCodes的代码。这些都在account / models.py文件中。课程和相关的“多对多”字段位于不同的模型文件Course / models.py中。我通常在代码中分别将它们分别称为amod和cmod。

在course / models.py中,我有一个导入语句:

from account import models as amod

class Course(ExtendedModel):
    stuff = stuff

我需要导入“课程”和“用户”之间的多对多模型/表的account / models.py文件,此处未显示。到现在为止还挺好。

在account / models.py文件中,我有CouponCode模型。每个实例都会被创建,然后在创建后可以分配给特定的Course对象,以允许学生使用它在系统中注册课程。

class CouponCode(ExtendedModel):
    assigned_course = UniqueIDForeignKey("course.Course", blank=True, null=True, related_name='assigned_coupon_code_set')
    ...
    ...

    @staticmethod
    def assign_batch(c, upper_limit):
        import course.models as cmod # Why is this allowed here?
        assert isinstance(c, cmod.Course)

        # Do other stuff here

该静态方法允许我传入课程对象和要分配给它的许多CouponCodes,然后它将为该课程分配下N个未分配的代码。我的问题来自断言。

我需要从course / models.py导入Course对象,以确保传入的对象实际上是Course的一个实例,但是如果我在文件顶部这样做,则会遇到问题,因为该文件已经被导入到course / models.py中。(将amod导入到cmod中,然后在amod中,我需要导入cmod)。

如果我在需要之前而不是在文件顶部将其导入方法中,为什么它允许我执行此操作?

布鲁诺·德斯胡里尔斯

导入模块时(第一次在给定进程中导入模块),将执行所有顶级语句(请记住这import 一个可执行语句)。因此,您不能让module1的import module2语句位于顶层,而module2语句位于顶层import module1-它显然无法工作。

现在,如果在module2中将import module1语句移动到函数中,则在实际调用该函数之前不会执行该语句,因此不会阻止module1导入module2。

请注意,这仍然被认为是一种不好的做法,多数情况下,循环依赖意味着您应该重构代码以避免发生问题(将两个模块所依赖的部分提取到三个模块都依赖的第三个模块中,而另一个都不依赖, (或简单地合并模块)-但由于其他限制,某些情况很复杂,因此最好将其作为最后解决方案。

此外,您不要需要导入模型引用它在一个ForeignKeyMany2Many现场-你可以传递一个"appname.ModelName"字符串,比照https://docs.djangoproject.com/en/1.8/ref/models/fields/#foreignkey

要引用在另一个应用程序中定义的模型,可以显式指定带有完整应用程序标签的模型。例如,如果上面的制造商模型在另一个称为生产的应用程序中定义,则需要使用:

class Car(models.Model):
    manufacturer = models.ForeignKey('production.Manufacturer')

解决两个应用程序之间的循环导入依赖关系时,此类参考很有用。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章