有多少大学生是写了很多年 Python 但是 import 一写还是会报错的?对,就是我。

此前我已经写过 Python 模块与包 的基本内容。但是好久之后回来看,发现自己写大的项目时候,对各部分认识还会出现问题。不过这部分问题主要是在 import 上。因此这里就来对 import 的机制进行进一步的解析。

# import 的两种方式

import 包括两种主要的方式,分别是绝对导入相对导入。在下面的讨论中,假设我们的项目的文件结构如下:

Proj/
├── src/
│   ├── data/
│   │   ├── __init__.py
│   │   └── utils/
│   │       └── cif2pyg.py
│   ├── models/
│   │       └── egnn.py
│   ├── utils/
│   │   └── logger.py
├── test/

# 绝对导入

也就是从项目的根目录中对文件进行引用。该方式是推荐的,因为这样不容易出现混淆问题。例如,从上述的 cif2pyg.py 中引入日志 logger.py , 那么需要在文件中写

from src.utils.logger import get_logger
# other codes

但是需要注意,这里需要让运行在根目录中进行。即使用

python -m src.data.utils.cif2pyg

运行,这里的 -m 指令代表运行的是项目中的一个模块,这样才能让顶层目录是项目根目录。

# 相对导入

相对导入以当前模块所在的包层级为准,只能在同一包内部进行,而且不能在顶层脚本中使用。该方式用于复杂的项目内部,从而避免过长的包名称。