Python/Django应用程序中解决循环依赖问题

2024-03-29 07:51:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个模型,它调用一个文件解析器(解析一个文件),文件解析器调用这个模型来保存对象。当前,代码如下所示:

型号.py

class Source(models.Model):
    ...

    def parse_file(self):
        from ingest.parser import FileParser
        ...

摄取.py

class FileParser()

    def save(self):
        from models import Source
        ...

不过,这个“工作”很好,在save方法中进行导入会增加我第一次使用它时的0.25s,因为它正在初始化导入。有没有更好的方法来实现上述目标?你知道吗


Tags: 文件对象方法frompy模型importself
1条回答
网友
1楼 · 发布于 2024-03-29 07:51:00

第一次加载模块时,命名空间为空的模块对象会立即放入sys.modules。在执行模块代码时填写名称空间。对模块的任何进一步引用只检索sys.modues中的引用,而不管它是否已完全加载。这就产生了两种解决问题的方法。你知道吗

方法1

由于导入的名称不在方法外部使用,因此只需确保它们在调用方法时存在,而不是在第一次创建方法时存在。你知道吗

您可以通过将有问题的导入放在相应文件的末尾来修复导入问题。这样,无论先加载哪个模块,其中的所有顶级名称都将在另一个模块尝试访问它们之前初始化:

型号.py

class Source(models.Model):
    ...

    def parse_file(self):
        ...

from ingest.parser import FileParser

摄取.py

class FileParser()
    def save(self):
        ...

from models import Source

如果首先加载models.py,则行from ingest.parser import FileParser将触发ingest.py的加载,但只有在模块命名空间中定义了Source之后。这意味着from models import Source将能够找到名称。同样的道理也适用于相反的顺序。你知道吗

如果您知道总是首先加载哪个模块,那么只需要将其中一个导入移到文件的末尾(首先加载的文件中的导入)。你知道吗

方法2

一个更简单的选择可能是只导入模块,而不是试图从中提取名称。这将允许您将导入保持在文件的顶部,因为可以使用空模块对象来满足循环导入:

型号.py

from ingest import parser

class Source(models.Model):
    ...

    def parse_file(self):
        # use parser. FileParser
        ...

摄取.py

import models

class FileParser()
    def save(self):
        # use models.Source
        ...

相关问题 更多 >