当前位置:首页>python>修复 Python 循环导入的一种方法

修复 Python 循环导入的一种方法

  • 2026-09-05 01:24:56
修复 Python 循环导入的一种方法
关注+星标,每天学习Python新技能

来源:网络

在 Python 中,循环导入是指两个文件各自尝试导入另一个文件, 当模块未完全初始化时导致失败, 最好的修复方法 将代码分层组织,以便导入,但有时它可以只需更改使用的 import 语句的样式即可。

假设有以下文件:

# one.pyfrom two import func_twodef func_one():    func_two()
# two.pyfrom one import func_onedef do_work():    func_one()def func_two():    print("Hello, world!")
# main.pyfrom two import do_workdo_work()

如果我们运行 main.py,我们会得到以下结果:

% python main.pyTraceback (most recent calllast):File"main.py", line 2, in <module>from two import do_workFile"two.py", line 2, in <module>from one import func_oneFile"one.py", line 2, in <module>from two import func_twoImportError: cannot importname'func_two'from partially initializedmodule'two' (most likely due to a circular import) (two.py)

   当 Python 导入模块时,它会逐行执行文件,文件中的每个全局变量(包括函数和类的顶级名称)都成为正在构造的模块对象的属性,在 two.py 中,我们在第 2 行从 one.py 导入,此时,模块已创建,但尚未定义任何属性,但我们尚未执行那些 def 语句,因此它们不存在,与函数调用一样,当运行 import 语句时,它开始执行导入的文件,直到导入完成才会返回当前文件。

one.py 的导入开始,其第 2 行尝试从 two 模块中获取名称,正如我们刚才所说,模块存在,但尚未定义名称,这给了我们错误。

我们可以导入整个模块,而不是从模块导入名称。我们所做的就是更改导入的形式,以及我们如何从导入的模块中引用函数,如下所示:

# one.pyimport two              def func_one():    two.func_two()     
# two.pyimport one            def do_work():    one.func_one()     def func_two():    print("Hello, world!")
# main.pyfrom two import do_workdo_work()

运行代码,我们得到:

% python main.pyHello, world!

    它之所以有效是因为 two.py 在第 2 行导入,然后 one.py 在其第 2 行导入,因为模块存在。它仍然像修复之前一样是空的,但现在我们不会尝试在导入期间在其中查找名称,一旦完成所有导入,和模块都定义了所有名称,我们可以从函数内部访问它们。

  这里的关键思想是“from two import func_two”在导入期间尝试查找,在它存在之前。通过使用“import two”将名称查找推迟到函数主体,可以让所有模块在我们尝试使用它们之前完全初始化,从而避免循环导入错误。

正如我在开始提到的,修复循环导入的最佳方法是构建代码,使模块没有这样的相互依赖关系,但这并不总是那么容易,这可以为你赢得一点时间让你的代码重新工作。

长按或扫描下方二维码,免费获取 Python公开课和大佬打包整理的几百G的学习资料,内容包含但不限于Python电子书、教程、项目接单、源码等等

推荐阅读

Python标准库里藏着的7个代码简化利器

为什么 asyncio 要这样设计?一篇文章讲清楚核心原理

3 分钟安装 openclaw | 零门槛到进阶 | 2026 年 3 月最新版

Python标准库里藏着的7个代码简化利器

点击 阅读原文 了解更多

最新文章

随机文章