python 中 import 介绍
Python 中从其他模块或库中导入方法或模块的方法是利用 import
关键字,但是,当工程比较复杂时,比如分成多个类别的库;当代码需要在 jupyter 中调用工程中的模块时,工程中各模块的互相引用就显得非常重要,如果导入模块的姿势不对,将导致程序无法运行。本篇总结常用的导入方法,对 import
关键字进行介绍。
import
常规的导入方法这里不再重复,直接介绍复杂工程中或多种运行方式(命令行、ipython、jupyter 等)下模块的导入。
工程结构
我这里创建了一个测试工程,目录结构如下:
1 | $ tree mytest |
其中,mytest 是工程名字,p1 和 p2 分别是两个库,里面分别有模块 q1,q2 和 q3,这里给出他们的内容:
1 | $ cat mytest/p1/q1.py |
绝对导入
请查看 mytest/p1/q1.py
和 mytest/p2/q3.py
,在 q3 中导入了上一层目录 p1 里面的 q1 模块,使用该模块的 add
方法。属于绝对导入,这种方法以工程名所在目录为家目录,使用时必须保证 mytest
在 python 运行时的环境变量中。
请查看 mytest/p1/q1.py
和 mytest/p2/q2.py
,在 q2 中导入了上一层目录 p1 里面的 q1 模块,使用该模块的 add
方法。在使用绝对导入前,增加了相对导入 from . import PROJECT_PATH
,使用动态的方式,将环境变量 mytest
在每次调用模块 q2 是添加到 python 环境变量中。
查看环境变量的方法:
1 | import sys |
命令行运行
此时,想要运行 q3.py
,可使用如下方法:
1 | cd mytest |
该方法的更多信息请查看另一篇文章:在命令行运行 python 程序的方法
注意,此时使用如下方法,将会报错:
1 | python p2/q3.py |
因为此方法以 q3.py
所在目录为主目录:'/home/jinzhongxu/PythonProjects/mytest/p2'
,运行时将该目录添加到 sys.path
中,但这与 q3.py
中的模块导入 from p1 import q1
不符,因为 p1 不在被访问到,它不在 p2 目录下。但,python -m p2.q3
会将 '/home/jinzhongxu/PythonProjects/mytest'
作为主目录,运行时将该目录添加到 sys.path
中,因此,在 q3.py
中能够使用 模块导入 from p1 import q1
.
运行 q2.py
1 | cd mytest |
但如下方法将会报错:
1 | cd mytest |
ipython 调用
如果运行方法如下,则同样能够通过:
1 | cd mytest |
可以看到,该方法同样会将 '/home/jinzhongxu/PythonProjects/mytest'
添加到 sys.path
中。
jupyter 调用
如果想在 jupyter 中随处都调用 p2/q2.py
和 p2/q3.py
,一种可行的方法是将 '/home/jinzhongxu/PythonProjects/mytest'
添加到环境变量中,此方法可参考:在 Python 中导入自己编写的模块,此时,在 jupyter 中调用方法如下:
1 | from p2 import q2 |
如果添加的是 '/home/jinzhongxu/PythonProjects'
到 module.pth 中,那么 from p2 import q3
方法将失效,因为 mytest
不在 sys.path
中,但 from p2 import q2
确定正常执行,因为,模块 q2.py
会在程序运行时动态导入 mytest
到 sys.path
中。
相对导入
请查看 mytest/p1/q1.py
和 mytest/p2/q4.py
,在 q4 中导入了上一层目录 p1 里面的 q1 模块,使用该模块的 add
方法。属于相对导入。
命令行运行
1 | cd mytest |
和
1 | cd mytest |
都将报错
ipython 调用
1 | $ ipython |
jupyter 调用
同样会报错。
结论
当代码只在命令行中运行时,可简单的采用 q3.py
的模式。运行方法采用 python -m q3.py
.
当代码不仅需要在命令行中运行,还需要再 jupyter 中调用时,配置环境变量很重要,推荐采用 q2.py
的模式。
尽量不要使用相对导入。