Python相对导入理解困惑:跨包导入bar类报错求助
解决Python包导入的相对导入报错问题
嘿,我完全懂你这种困惑——Python的导入机制刚接触时确实容易绕晕,哪怕查了一堆资料还是摸不着头脑。让我一步步帮你理清楚问题出在哪,以及怎么解决。
问题根源:直接运行脚本导致相对导入失效
你遇到的ValueError: attempted relative import in non-package,本质原因是你直接运行了foo.py这个脚本。
当你用python src/foo/foo.py这种方式启动时,Python会把foo.py所在的src/foo/目录当成顶层模块目录,而不是把src作为整个项目包的根目录。这时候foo.py被当作独立脚本,它的__name__属性是__main__,而不是src.foo.foo——相对导入(比如..这种写法)只能在包内部的模块中使用,不能在直接运行的脚本里生效。
而test_foo.py能正常导入foo,是因为你大概率是在src/foo/目录下运行它,或者src/foo/刚好在Python的搜索路径里,这时候foo.py被当作顶层模块导入,自然没问题。
两种可行的解决方案
方案一:改用绝对导入(推荐)
如果你把src作为整个项目的包根目录,用绝对导入会更直观且不容易出错。
- 在
foo.py里修改导入语句:
from bar.bar import bar
(注:按Python的PEP8规范,类名建议用大写开头,比如Bar,这样代码可读性更高,你可以根据实际情况调整)
- 确保
src所在的父目录在Python的搜索路径中:- 最简单的方式是从项目根目录(
src的父目录)下,用模块方式运行foo.py:python -m src.foo.foo - 或者把
src目录添加到PYTHONPATH环境变量中:- Linux/macOS:
export PYTHONPATH="/path/to/your_project/src:$PYTHONPATH" - Windows:
set PYTHONPATH=C:\path\to\your_project\src;%PYTHONPATH%
foo.py也不会报错了。 - Linux/macOS:
- 最简单的方式是从项目根目录(
方案二:正确使用相对导入(需避免直接运行脚本)
如果你坚持用相对导入,必须把foo.py当作包的一部分来运行,不能直接执行脚本文件。
从项目根目录(src的父目录)下执行:
python -m src.foo.foo
这时候foo.py的__name__会变成src.foo.foo,属于包的一部分,你之前写的相对导入语句:
from ..bar.bar import bar
就能正常工作了。
内容的提问来源于stack exchange,提问作者Aaron
相关产品推荐
相关产品推荐

