行则将至

人生在勤,不索何获

0%

Python import 导入其他脚本

假设有如下目录结构:

1
2
3
4
5
6
7
-- dir0
  | file1.py
  | file2.py
  | dir3
    | file3.py
  | dir4
    | file4.py

dir0 文件夹下有 file1.pyfile2.py 两个文件 和 dir3dir4 两个子文件夹,dir3 中有 file3.py 文件,dir4 中有 file4.py 文件。

1. 导入同级模块

python 导入同级模块(在同一个文件夹中的 py 文件)直接导入即可。

1
import xxx

如在 file1.py 中想导入 file2.py,注意无需加后缀 ".py":

1
2
3
import file2
# 使用file2中函数时需加上前缀"file2.",即:
# file2.fuction_name()

2. 导入下级模块

导入下级目录模块也很容易,需在下级目录中新建一个空白的__init__.py 文件再导入

1
from dirname import xxx

如在 file1.py 中想导入 dir3 下的 file3.py,首先要在 dir3 中新建一个空白的_init___.py 文件。

1
2
3
4
5
6
7
8
-- dir0
  | file1.py
  | file2.py
  | dir3
   | __init__.py
   | file3.py
  | dir4
   | file4.py

再使用如下语句:

1
2
# plan A
from dir3 import file3

或是

1
2
3
# plan B
import dir3.file3
# import dir3.file3 as df3

但使用第二种方式则下文需要一直带着路径 dir3 书写,较为累赘,建议可以另起一个别名。

3. 导入上级模块

要导入上级目录下模块,可以使用 sys.path:  

1
2
3
import sys 
sys.path.append("..")
import xxx

如在 file4.py 中想引入 import 上级目录下的 file1.py: file4.py

1
2
3
import sys 
sys.path.append("..")
import file1
python 中 sys.path 的作用?

当使用 import 语句导入模块 时,解释器会搜索当前模块所在目录 以及 sys.path 指定的路径 去找需要 import 的模块,所以这里是直接把上级目录加到了 sys.path 里。

“..” 的含义: 等同于 linux 里的‘..’,表示当前工作目录的上级目录。实际上 python 中的‘.’也和 linux 中一致,表示当前目录。

4. 导入隔壁文件夹下的模块

如在 file4.py 中想引入 import 在 dir3 目录下的 file3.py。

这其实是前面两个操作的组合,其思路本质上是将上级目录加到 sys.path 里,再按照对下级目录模块的方式导入。

同样需要被引文件夹也就是 dir3 下有空的__init__.py 文件。

1
2
3
4
5
6
7
8
-- dir
  | file1.py
  | file2.py
  | dir3
    | __init__.py
    | file3.py
  | dir4
    | file4.py

同时也要将上级目录加到 sys.path 里: file4.py

1
2
3
import sys
sys.path.append("..")
from dir3 import file3

5. 常见错误及 import 原理:

在使用直接从上级目录引入模块的操作时:

1
from .. import xxx

经常会报错:

1
ValueError: attempted relative import beyond top-level package

这是由于相对导入时,文件夹实质上充当的是 package,也就是包的角色(比如我们常用的 numpy、pandas 都是包)。如果 python 解释器没有认同该文件夹是 package,那么这就是一个普通的文件夹,无法实现相对导入。

python 中文件夹作为 package 需要满足的条件?

  1. 文件夹中必须 存在有__init__.py 文件,可以为空。
  2. 不能作为顶层模块来执行该文件夹中的 py 文件。

6. 导入最佳实践

  • 把项目根目录加入环境变量(手动或通过脚本)
  • import 导入路径以项目根目录下的源码目录 src 为起始, 如下:
    1
    2
    3
    from src.core.logger_class import Logger  
    from src.core.config_class import LoadConfig
    from src.core.db_class import MySql, Mongo, Redis, Kafka
    参考:Python Import module from different directory

各种导入示例

参考

python - Relative imports for the billionth time - Stack Overflow

Backlinks: