我使用的存储库的结构如下:
在 myrepo/src/ 中有: 主要.py core.py
和
somepkg
somepkg有 init .py和其他python文件。 somepkg 不是任何文件中的类或函数。
在 main.py 中,我看到:
from . import core from . import somepkg
我的问题是 from 和 . import 和以下内容?
import core import somepkg
另外,如果我更改为 import core 并导入 somepkg,我实际上开始出现循环依赖错误。
提前谢谢您!
如果我保留:
from . import core from . import somepkg
我实际上得到: ImportError:尝试在没有已知父包的情况下进行相对导入。
如果我更改为
import core import somepkg
我开始得到:ImportError:无法导入...(很可能是由于循环导入)
让我们来分析一下 Python 的导入机制,以及你的代码中出现错误的原因,并最终找到解决方法。
理解相对导入
from . import something
是一种
相对导入
的语句,它指示 Python 从当前包的上下文("." 表示当前目录)导入一个模块或包。
关键在于 "包" 的概念
。
你的问题:缺少
__init__.py
文件
你遇到的问题根源在于
src
目录以及
somepkg
目录没有被 Python 识别为包。为了让 Python 将一个目录视为包,该目录下必须包含一个
__init__.py
文件。这个文件可以是空的,但它的存在至关重要。
错误解析
-
"ImportError: attempted relative import with no known parent package" :当你使用相对导入 (
from . import ...
) 时,Python 无法确定当前模块所属的包,因为它没有在src
目录中找到__init__.py
。 -
"ImportError: cannot import ... (most likely due to a circular import)" :当你使用绝对导入 (
import core
,import somepkg
) 时,你可能在core.py
和somepkg
内部存在相互导入的情况,从而导致循环依赖。例如,core.py
可能导入了somepkg
中的某个模块,而该模块又导入了core.py
。
解决方案
-
创建
__init__.py
文件:
在
src
目录和
somepkg
目录下分别创建空的
__init__.py
文件。
- 使用绝对导入:
将
main.py
中的导入语句修改为绝对导入:
python
import core
import somepkg
-
解决循环依赖(如果存在):
-
重构代码: 尝试重新组织你的代码,将相互依赖的函数或类移动到一个共同的模块中,或者将部分逻辑提取到新的模块,以打破循环依赖。
- 延迟导入: 将其中一个模块的导入语句移动到需要使用该模块的函数内部。这样可以避免在模块加载时就进行导入,而是等到实际需要时再进行。
示例
假设
somepkg
中有一个
module1.py
文件:
# src/somepkg/module1.py
def my_function():
print("Hello from somepkg.module1!")
那么你可以在
main.py
中这样使用它:
# src/main.py
import core
import somepkg.module1
core.some_function()
somepkg.module1.my_function()
总结
通过添加
__init__.py
文件并使用绝对导入,你可以解决导入问题。如果遇到循环依赖,你需要仔细分析代码结构并进行相应的调整。