我创建的一些小项目具有以下目录结构:
my_project/
├─ docs/
├─ code/
│ ├─ __init__.py
│ ├─ main.py
│ └─ tools.py
├─ README
└─ .gitignore
在main.py
中,我使用以下绝对导入语句从tool()
模块中导入tools.py
函数:
from tools import tool
当我查看一些著名的(并且可能也写得很好)软件包的源代码时,我发现了一个相似的结构,但是风格不同的绝对导入语句:
({Django,/django/core/paginator.py)
from django.utils.functional import cached_property
from django.utils.inspect import method_has_no_args
为什么父django
目录包含在import语句中?这是导入模块的首选方法吗?当我将逻辑应用于项目并更改tool()
函数的导入时,如下所示:
from code.tests import test
,然后在终端中运行以下命令:
python3 main.py
它当然会引发ModuleNotFoundError
。
我想了解为什么这些软件包使用这种风格的导入语句(这与我的不同,不适用于我自己的项目)。我仍在学习Python,因此也很高兴阅读一些链接。
答案 0 :(得分:1)
它不是像您假设的那样引用本地目录,而是实际模块本身在其安装路径中。
安装模块后,Python解释器将以django
的形式访问它,因此它基本上是在参考模块的安装位置。解释基本上是在尝试做:
django
路径?django
路径?ModuleNotFoundError
。按照此逻辑,程序包使用绝对导入,因为paginator.py
位于django/core
路径中,因此除非它直接将自身引用为{从django/utils
或使用相对导入(site-packages
等)安装的模块。 This link has some more details.
要比较苹果与您所用的苹果-尝试在from ..utils.functional import cached_property
下有一个test.py
模块。您会发现,在没有绝对导入或相对导入的情况下,无法访问my_project/utils
下的该模块,因为Python Interpreter仅知道您当前的工作目录(main.py
,假设您直接运行core
,或您实际执行解释器的任何地方)以及可通过环境路径访问的任何其他模块目录。