前言
提示:这里可以添加本文要记录的大概内容:
“most likely due to a circular import”翻译为“很可能是由于循环导入”,提示 ImportError,在对自定义模块的引用中出现。Python 学习手册《编程常见问题》对“How can I have modules that mutually import each other?”的回答解决了这个问题。本文是对这一内容的抄录和整理。
提示:以下是本篇文章正文内容,下面案例可供参考
1 示例
如下示例来自学习手册:

2 解释器的操作步骤

3 错误分析
对上述操作步骤的错误分析:
- The last step fails, because Python isn’t done with interpreting foo yet and the global symbol dictionary for foo is still empty.
最后一步失败了,因为 Python 还没有完成对 foo 的解释,而且 foo 的全局符号字典仍然是空的。 - The same thing happens when you use import foo, and then try to access foo.foo_var in global code.
当您使用 import foo,然后尝试在全局代码中访问 foo.foo_var 时,也会发生同样的事情。
4 解决办法
这个问题有(至少)三种可能的解决方法。
- Guido van Rossum recommends avoiding all uses of from import …, and placing all code inside functions. Initializations of global variables and class variables should use constants or built-in functions only. This means everything from an imported module is referenced as < module >.< name >.
Guido van Rossum 建议避免使用 from < module > import …,并将所有代码放在函数中。 全局变量和类变量的初始化应该只使用常量或内置函数。 这意味着导入模块中的所有内容都被引用为 < module >.< name >。 - Jim Roskind suggests performing steps in the following order in each module:
建议在每个模块中按以下顺序执行:
- exports (globals, functions, and classes that don’t need imported base classes)
导出(不需要导入基类的全局变量、函数和类) - import statements
import 语句 - active code (including globals that are initialized from imported values).
活动代码(包括从导入值初始化的全局变量)。
Guido van Rossum doesn’t like this approach much because the imports appear in a strange place, but it does work.
Guido van Rossum 不太喜欢这种方法,因为导入出现在一个陌生的地方,但它确实有效。
- Matthias Urlichs recommends restructuring your code so that the recursive import is not necessary in the first place.
Matthias Urlichs 建议重新构建您的代码,以便一开始就不需要递归导入。
这些解决方案并不相互排斥。
5 运行示例
体会一下循环导入的运行实例:

总结
- 我个人推荐 Guido van Rossum 的建议:
1.1. 避免使用 from < module > import …,并将所有代码放在函数中。
1.2. 全局变量和类变量的初始化应该只使用常量或内置函数。
1.3. 这意味着导入模块中的所有内容都被引用为 < module >.< name >。 - 我的老师尹成有一个串联类的示例里,直接用 self 变量解决了,也值得学习!
2.1. 实际上避免了创建两个实例的问题。


本文详细介绍了Python中ModuleNotFoundError和ImportError的常见原因,特别是由于循环导入导致的错误。通过实例分析了解解释器的操作步骤,提出了解决此类问题的三种方法,包括将代码放入函数、调整导入顺序和重构代码。Guido van Rossum的建议是避免from...import...,使用模块名.变量名的方式,并限制全局变量初始化。
848

被折叠的 条评论
为什么被折叠?



