Python中无法import同级package下的代码如何解决?

我正在开发一个简单的 django 应用,目录结构如下:

django_intuitive_pagination/
    ├── example
    │   ├── config
    │   │   ├── settings.py
    │   ├── items
    │   │   └── views.py
    │   └── manage.py
    ├── intuitive_pagination
    │   ├── __init__.py
    │   ├── mixins.py
    │   └── views.py

我现在将 intuitive_pagination 作为 app 加入到 example/settings.py 的 INSTALLED_APPS 列表中,但是 django 报错说:ImportError: No module named 'intuitive_pagination'

不加入 INSTALLED_APPS 中,但是我在 items/views 中引入了 intuitive_pagination 包中的代码,如下:

example/items/views.py

from intuitive_pagination.views import PaginationListView

还是报错说:ImportError: No module named 'intuitive_pagination'

请问是哪里出了问题?项目的顶层目录已经加入 sys.path 中了:

>>> sys.path
[..., '/home/light/Workspace/PycharmProjects/DjangoProjects/django_intuitive_pagination']

似乎是 python 找不到 intuitive_pagination,但不应该呀? intuitive_pagination 不是已经是一个合法的 package 了么?


Python中无法import同级package下的代码如何解决?

16 回复

intuitive_pagination 是顶级包么。。
用相对导入吧


这个问题很常见,通常是因为Python解释器找不到你的模块。核心原因是你的项目目录没有被正确添加到Python的模块搜索路径(sys.path)里。

最直接、标准的解决方案是:将你的项目变成一个可安装的包。

假设你的项目结构是这样的:

my_project/
├── main.py
└── my_package/
    ├── __init__.py
    └── module_a.py

main.py 里,你想 import my_package.module_a,但直接运行 python main.py 可能会失败。

解决方法:在项目根目录创建一个 setup.py 文件,并使用 pip install -e . 进行开发模式安装。

  1. 创建 setup.py (放在 my_project/ 目录下):
from setuptools import setup, find_packages

setup(
    name="my_project",
    version="0.1",
    packages=find_packages(),
)
  1. 在项目根目录(my_project/)下,运行安装命令
pip install -e .

这个 -e 参数代表“可编辑模式”,它不会真的复制文件,而是在系统里创建一个链接指向你的项目目录。这样,无论你在哪个目录运行Python,都能正确导入你的包。

  1. 现在,在你的 main.py 中,就可以正常导入了
# main.py
from my_package import module_a

# 或者
import my_package.module_a

module_a.some_function()

为什么这是最佳实践?

  • 路径清晰:它明确地定义了你的包结构,Python能准确知道 my_package 在哪里。
  • 环境独立:结合虚拟环境(如 venv),可以隔离不同项目的依赖。
  • 便于分发:为将来打包、发布你的代码做好准备。

其他临时方案(不推荐长期使用)

  • 在代码里手动修改 sys.path(破坏了Python的包管理机制,容易造成混乱)。
  • 设置 PYTHONPATH 环境变量(对于复杂项目,管理起来麻烦)。

总结:用 setup.pypip install -e . 一劳永逸。

每个目录都要加 init.py?

django_intuitive_pagination 有__init__.py 么?

intuitive_pagination 是项目目录 django_intuitive_pagination 下的一个包

都有 init.py
django_intuitive_pagination 下也加了试过,但还是一样报错

是不是用 python django startapp 创建的 app?

items 是的,python manage.py startapp

config/items
这两个目录下也需要放 init.py
另外你在 settings.py 里面 print sys.path 看看。
可能你在 shell 下看到的 sys.path 和项目运行时的不一样。

检查你的 working directory

你打印的 sys.path 不是运行时的吧

每个包下面都加 init.py, 然后终端运行 PYTHONPATH=path/to/src python what/you/want/to/run.py

概念思路梳理一下
django_intuitive_pagination 文件夹下面,每个文件夹都需要加入__init__.py ,形成包,然后就可以使用 import

使用 django_intuitive_pagination 的两种情况。
外部使用,这个不会遇见问题,按照路径就可以了。
内部使用,通过小圆点 . 来分包的层次,也就是你现在遇见的问题!

至于 path 包到全局路径,又是另外一个知识点。

最近我也被导包问题弄的死去活来

最后我的解决方式是 在文件上面加入当前目录的路径

你是直接编译的单独文件还是运行整个项目?从 django_intuitive_pagination 目录下的主程序(如 main.py 或者 run.sh 之类)开始执行,是可以在 example 文件夹里任意.py 直接 import intuitive_pagination 没问题的。应该是单独文件运行和整个项目运行时的环境不同的缘故。
http://blog.csdn.net/luo123n/article/details/49849649
这篇博客里有介绍一些,但是他用的 import package.subpackage 的方法我试了不管用,省去 package 直接 import subpackage 是可以的。另外文章下面提到的用__main__来单独运行某个文件,我还没试过,你可以试一下。

你用的是 py3.6 吧?

回到顶部