Python 3中相对导入的正确使用及调试问题咨询
解决Python 3中相对/绝对导入的冲突问题
我完全懂这种两头卡壳的痛苦——相对导入触发ImportError,换绝对导入吧PyCharm调试又跑到已安装的包去,完全不执行本地代码,太闹心了!咱们一步步拆解问题,找到最适合你的解决方案。
首先得明确咱们的项目结构,假设你现在的结构大概是这样(如果不是,调整成类似规范结构就行):
my_project/ ├── my_package/ │ ├── __init__.py # 这里声明了MyClass │ └── run.py # 你要运行的脚本 └── setup.py(如果是可安装项目的话)
方案1:调整项目结构(最推荐)
踩过无数次坑的过来人告诉你,把入口脚本run.py移出包目录,放到项目根目录是最稳妥的做法:
my_project/ ├── my_package/ │ └── __init__.py # 含MyClass └── run.py
然后在run.py里用绝对导入:
from my_package import MyClass # 你的业务代码 if __name__ == "__main__": obj = MyClass() # ...
接下来解决PyCharm调试的问题:
- 右键点击
my_project文件夹,选择Mark Directory as > Sources Root - 这样PyCharm会把这个目录放到
sys.path的最前面,调试时优先加载本地的my_package,而不是你之前安装的同名包。
方案2:如果run.py必须放在包内
要是因为某些原因,run.py必须留在my_package目录里,那别直接双击或用python my_package/run.py运行,而是用Python的模块运行方式:
- 打开终端,切换到项目根目录
my_project/ - 执行命令:
python -m my_package.run
这时候Python会把my_package当成一个正规的包来处理,你就可以在run.py里用相对导入了:
from . import MyClass if __name__ == "__main__": obj = MyClass() # ...
为什么直接运行不行?因为Python把直接执行的脚本当成「顶级模块」,它所在的目录会被加到sys.path最前面,而不是把项目根目录加进去,导致相对导入找不到上级包。用-m参数运行就会纠正这个问题。
方案3:Editable Install(适合可分发项目)
如果你的项目是要打包分发的(有setup.py或pyproject.toml),那用「可编辑安装」就能一劳永逸解决所有问题:
- 切换到项目根目录
my_project/ - 执行命令:
pip install -e .
这个命令会把你的本地项目以「链接」的形式安装到Python环境里,不管你用绝对导入还是PyCharm调试,都会优先使用本地的代码,完全不用担心和已安装包冲突。
为什么你之前的方法会失效?
- 相对导入报错:直接运行包内的脚本时,Python不把它当成包的一部分,导致
.无法解析为当前包 - 绝对导入跑错代码:PyCharm默认没把你的项目根目录设为「Sources Root」,所以会优先从
site-packages里找已安装的同名包
内容的提问来源于stack exchange,提问作者Евгений Шахов




