Python中子模块引用问题:跨模块调用提示父模块未找到
我来帮你拆解这个问题——核心是Python模块搜索路径的机制,和空的__init__.py关系不大(Python 3.3+里,空的__init__.py已经足够标记一个文件夹为Python包了,所以你不需要修改它)。
为什么根目录的脚本能正常运行?
当你在tmodules目录下运行call_module1_module2.py时,Python会自动把当前工作目录(也就是tmodules文件夹)加入到模块搜索路径sys.path里。所以module1和module2作为tmodules下的子包,直接用from module1.file1 import *就能被找到,毫无问题。
为什么module2/file2.py里的导入会报错?
当file2.py被call_module1_module2.py导入时,它的“上下文”是作为module2包的一部分,此时Python的搜索路径里并没有自动包含tmodules的父目录,也不会把tmodules本身作为顶层包来识别。你写from tmodules.module1.file1 import *时,Python会去sys.path里找名为tmodules的包,但找不到,所以抛出“module not found”错误。
几种可行的解决方案
1. 使用相对导入(推荐,符合Python包的设计规范)
在file2.py里用上一级目录的相对引用,直接指向module1:
from ..module1.file1 import function1
- 这里的
..表示当前包(module2)的上一级目录,也就是tmodules目录,这样就能正确找到module1.file1了。 - 注意:相对导入只能在被当作包的一部分导入时生效,不能直接运行
file2.py作为独立脚本(比如python module2/file2.py会报错)。如果要直接运行它,得用包的方式启动:python -m module2.file2(在tmodules目录下执行)。
2. 手动把项目根目录加入sys.path
如果不想用相对导入,可以在file2.py的开头添加代码,把tmodules目录的绝对路径加入到Python的搜索路径里:
import sys import os # 获取当前文件的绝对路径,往上两级就是项目根目录tmodules root_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(root_dir) # 现在就能直接导入了 from module1.file1 import function1
这种方法不需要修改环境变量,也能兼容直接运行file2.py的场景。
3. 设置PYTHONPATH环境变量
把项目根目录tmodules的路径添加到PYTHONPATH环境变量中,这样Python会全局搜索这个路径下的包。
- Linux/macOS终端:
export PYTHONPATH="/绝对路径/to/tmodules:$PYTHONPATH" - Windows命令行:
set PYTHONPATH=C:\绝对路径\to\tmodules;%PYTHONPATH%
设置后,不管你在哪个目录运行脚本,都能直接用from module1.file1 import *导入。
关于__init__.py的补充
你现在的空__init__.py完全没问题,Python 3.3及以上版本支持没有__init__.py的命名空间包,但空文件也能正常标记为普通包,所以不需要修改它来解决这个导入问题。
内容的提问来源于stack exchange,提问作者searchx searchy

