python的import问题:绝对路径,相对路径,sys.path.append
python的import问题
- 原理
在Python中,一个.py文件就称之为一个模块(Module),包含.py文件的文件夹,且里面有一个__init_.py
的文件夹称为包(Package),init.py可以是空文件,也可以有Python代码,因为__init__.py
本身就是一个模块,它的模块名就是包名。在python脚本被执行,python导入其他包或模块时,python会根据sys.path列表里的路径寻找这些包或模块。如果没找到的话,程序就会报错。
>>> import sys
>>> print(sys.path)
['', 'C:\\Users\\SONG\\Anaconda3\\python37.zip', 'C:\\Users\\SONG\\Anaconda3\\DLLs', 'C:\\Users\\SONG\\Anaconda3\\lib', 'C:\\Users\\SO
NG\\Anaconda3', 'C:\\Users\\SONG\\AppData\\Roaming\\Python\\Python37\\site-packages', 'C:\\Users\\SONG\\Anaconda3\\lib\\site-packages'
, 'C:\\Users\\SONG\\Anaconda3\\lib\\site-packages\\win32', 'C:\\Users\\SONG\\Anaconda3\\lib\\site-packages\\win32\\lib', 'C:\\Users\\S
ONG\\Anaconda3\\lib\\site-packages\\Pythonwin']
程序中要导入包或模块就需要在这些路径中进行查找,分为三种情况:
① 当前执行脚本(主动执行,而不是被其他模块调用)所在路径。上面例子是在交互界面进行操作,没有执行脚本,所以为空字符串。
②python内置的标准库路径,PYTHONPATH。
③安装的第三方模块路径。
- 分析
- python module_0.py为前提
package_0
├── module_0.py
├── module_1.py
├── package_1
│ ├── module_2.py
│ ├── module_3.py
│ └── package_2
│ ├── module_21.py
│ └── module_22.py
└── package_3
└── module_4.py
python module_0.py,即/home/…/package_0会被添加到 sys.path 中,可以通过该路径找到其他模块的,比如下面这些语句是不会报错的。
# module_0.py
import module_1
from package_1 import module_2
from package_1.package_2 import module_21
而下面的语句会报错:ModuleNotFoundError: No module named 'module_3’
# module_2.py
import module_3
原因:执行 python module_0.py 时,把路径(’/home/…/package_0’)添加到 sys.path 中,该路径下就不能在 module_2.py 中通过这种方式找到module_3,因为module_2.py 在路径/home/…/package_0/package_1下。
- 绝对路径:从当前执行脚本所在路径/…/需要的module
# module_2.py
from package_1 import module_3
# module_21.py
from package_1.package_2 import module_21
-
相对路径
单点表示引用的模块或包与当前模块在同一目录中(同一个包中)。
两点表示在当前模块所在位置的父目录中。
# module_2.py
from . import module_3
from .package_2 import module_21
# module_21.py
from .. import module_2
下面的语句会报错:ValueError: attempted relative import beyond top-level package
# module_2.py
from ..package_3 import module_4
原因:试图在*包(top-level package)之外进行相对导入。也就是说相对导入只适用于*包之内的模块。
如果将 module_0.py 当作执行模块,则和该模块同级的 package_1 和 package_3 就是*包(top-level package),而 module_2 在package_1中,module_0、module_1和module_4都在 package_1之外,所以调用这三个模块时,就会报这个错误。
下面的语句会报错:ModuleNotFoundError: No module named ‘main.package_1’; ‘main’ is not a package
# module_0.py
from .package_1 import module_2
原因:用了相对导入的模块文件不能作为顶层执行文件,即不能 python module_0.py
- sys.path.append
# module_2.py
sys.path.append(os.path.dirname(__file__))
import module_3
from package_2 import module_21
# module_2.py
sys.path.append(os.path.join(os.path.dirname(__file__), '../package_3'))
import module_4
上一篇: java相对路径按行读取文件
推荐阅读
-
详解在Python中以绝对路径或者相对路径导入文件的方法
-
解决python3 安装完Pycurl在import pycurl时报错的问题
-
SpringMVC使用ModelAndView的相对路径和绝对路径的问题
-
解决Python import .pyd 可能遇到路径的问题
-
python读写的时候的相对路径问题
-
Winform中在使用VS+svn进行协同开发时添加引用时的相对路径和绝对路径的问题
-
解决python3.x安装numpy成功但import出错的问题
-
Python import模块的缓存问题解决方案
-
解决Python库在IDLE无法正常import的问题(Module Not Found)
-
关于绝对路径和相对路径的问题?