gpt4 book ai didi

python - 解决 python/django 应用程序中的循环依赖

转载 作者:太空狗 更新时间:2023-10-29 21:48:10 25 4
gpt4 key购买 nike

我有一个调用文件解析器(解析文件)的模型,该文件解析器调用模型来保存对象。目前,代码看起来像这样:

模型.py

class Source(models.Model):
...

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

摄取.py

class FileParser()

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

这个“工作”很好,但是,在我第一次必须使用它时,在保存方法中执行导入会增加大约 0.25s,因为它正在初始化导入。是否有更好的方法来执行上述操作?

最佳答案

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

方法一

由于导入的名称不在方法外部使用,您只需确保它们在调用方法时存在,而不是在首次创建时存在。

您可以通过将有问题的导入放在各自文件的末尾来解决导入问题。这样,无论首先加载哪个模块,其中的所有顶级名称都将在其他模块尝试访问它们之前被初始化:

模型.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 将能够找到该名称。倒序也一样。

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

方法二

一个更简单的替代方法可能是只导入模块,而不是尝试从中提取名称。这将允许您将导入保留在文件的顶部,因为空模块对象将可用于满足循环导入:

模型.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
...

关于python - 解决 python/django 应用程序中的循环依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54122133/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com