You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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的模块运行方式:

  1. 打开终端,切换到项目根目录my_project/
  2. 执行命令:
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.pypyproject.toml),那用「可编辑安装」就能一劳永逸解决所有问题:

  1. 切换到项目根目录my_project/
  2. 执行命令:
pip install -e .

这个命令会把你的本地项目以「链接」的形式安装到Python环境里,不管你用绝对导入还是PyCharm调试,都会优先使用本地的代码,完全不用担心和已安装包冲突。

为什么你之前的方法会失效?

  • 相对导入报错:直接运行包内的脚本时,Python不把它当成包的一部分,导致.无法解析为当前包
  • 绝对导入跑错代码:PyCharm默认没把你的项目根目录设为「Sources Root」,所以会优先从site-packages里找已安装的同名包

内容的提问来源于stack exchange,提问作者Евгений Шахов

火山引擎 最新活动