Python3.8 Tetris项目导入问题:单独运行子模块找不到code_base模块
导入报错的底层逻辑
Python执行脚本时会自动把脚本所在的目录加入sys.path(模块搜索路径列表),导入模块时只会从sys.path包含的路径里查找对应模块:
- 运行根目录的run.py时,sys.path会加入Jstris根目录路径,根目录下的code_base、game_mode都是可被搜索到的包,所以所有导入都正常。
- 单独运行code_base下的functions.py时,sys.path只会加入Jstris/code_base路径,此时搜索路径里不存在code_base这个父级包,自然会抛出ModuleNotFoundError。
解决方案
不用接受无法单独运行子模块的现状,有多个合规的方案可以实现双兼容:
- 方案1:保持现有代码不变,用模块模式运行子文件(最推荐)
不需要修改任何现有导入代码,只要你需要单独运行functions.py时,不要cd到code_base目录执行python functions.py,而是在Jstris根目录下执行:python -m code_base.functions
该命令会将当前工作目录(Jstris根目录)自动加入sys.path,同时将functions作为包的子模块运行,完全兼容现有导入逻辑。 - 方案2:修改为包内相对导入,符合Python包开发规范
将functions.py中的导入语句改为相对导入写法:
这种写法是Python包内模块互相导入的标准写法,配合上述-m参数运行即可同时兼容整体项目运行和单独运行。from .constants import PLAY_WIDTH, PLAY_HEIGHT from .tetromino import Tetromino # 单独运行时的执行逻辑要加入口判断 if __name__ == '__main__': # 这里放你单独运行functions.py要执行的测试/运行代码 pass - 方案3(仅临时测试用,不推荐正式使用)
可以在functions.py开头手动将项目根目录加入sys.path:
该写法硬编码了路径搜索逻辑,灵活度低,不适合正式项目使用。import sys from pathlib import Path sys.path.append(str(Path(__file__).parent.parent.resolve()))
现有结构是否符合规范
你当前的项目结构和导入写法完全符合Python常规开发规范:入口文件放在项目根目录,通用逻辑和业务逻辑拆分到不同子包,没有问题。如果子模块本身不需要单独作为入口运行,完全不用特意适配单独运行的能力,保持现有写法即可。
内容的提问来源于stack exchange,提问作者Rabinzel
相关产品推荐
相关产品推荐

