前言:本文会以windows和Linux两个平台之下进行说明,python的模块导入的搜索顺序是怎样的。
一、导入模块的搜索顺序:
(1)首先导入内建模块。首先判断这个module是不是built-in即内建模块,如果是内建模块则引入内建模块,如果不是则在一个称为sys.path的list中寻找;
(2)在sys.path返回的列表中寻找。sys.path在python脚本执行时动态生成,它返回的是一个列表,这个列表包含了以下几部分。包括以下5个部分:
下面的五个搜索路径是有先后顺序的哦!!!
- 程序的根目录(即当前运行python文件的目录)
- PYTHONPATH环境变量设置的目录
- 标准库的目录
- 任何能够找到的.pth文件的内容
- 第三方扩展的site-package目录
因为内建模块是随着解释器一起的,不用自己管,我们只需要查看sys.path这个顺序即可。
1.1 windows平台之下
在这个示例中,我是用的是anaconda环境,在环境之下创建了一个pytorch1.2.0的新环境, 执行如下:
import sys
sys.path
'''返回的列表为:
['', # 运行程序的根目录
'D:\\ProgramData\\Anaconda3\\envs\\pytorch1.2.0\\python36.zip', # 这几个是python标准库目录
'D:\\ProgramData\\Anaconda3\\envs\\pytorch1.2.0\\DLLs',
'D:\\ProgramData\\Anaconda3\\envs\\pytorch1.2.0\\lib',
'D:\\ProgramData\\Anaconda3\\envs\\pytorch1.2.0',
'C:\\Users\\Administrator\\AppData\\Roaming\\Python\\Python36\\site-packages',
'D:\\ProgramData\\Anaconda3\\envs\\pytorch1.2.0\\lib\\site-packages' # 最后面这个是第三方模块所在的目录
]
'''
'''
# 注意:这里是没有设置PYTHONPATH 环境变量的路径值的,也没有创建.pth文件
'''
(1)关于环境变量PYTHONPATH
PYTHONPATH 这个目录是可配置的),python会搜索PYTHONPATH环境变量里列出的所有目录,因为这个搜索在标准库之前,所以要小心不要覆盖一些标准库的同名模块。
(2)什么是*.pth文件
问题一:什么是 *.pth文件?
路径配置文件的扩展名是”.pth”,它的作用是在该文件中放置一些列需要让python解释器查找的路径。
问题二:*.pth文件放在哪里?
Python 在遍历已知的库文件目录过程中(在遍历sys.path的路径的过程中要能够找得到才行哦!!!),如果见到一个* .pth 文件,就会将文件中所记录的路径加入到 sys.path 设置中,于是 .pth 文件所指明的库也就可以被 Python 运行环境找到了。所以这个文件不是乱放的,不要能够被解释器找得到的地方才行。
当然在上面的打印出来的sys.path里面的那些路径里面都可以放置,因为那些路径解释器都能够找得到,但是一般为了方便管理,我们放置在下面两个位置之一:
import site
site.getsitepackages()
'''
['D:\\ProgramData\\Anaconda3\\envs\\pytorch1.2.0', # python的根目录
'D:\\ProgramData\\Anaconda3\\envs\\pytorch1.2.0\\lib\\site-packages'] #python的第三方库目录
'''
问题三:*.pth文件里面内容怎么写?
*.pth文件里面放置的其实就是几个目录。其中的每一行包含一个单独的路径,该路径会添加到sys.path列表中,”.pth”中的路径既可以是绝对路径,也可以是相对路径,如果是相对路径,则是相对于包含”.pth”文件的路径而言的。
比如我自己在 D:\ProgramData\Anaconda3\envs\pytorch1.2.0
这个目录之下新建一个文本文档,然后在里面放入一个目录, F:/pytorch
然后将文件后缀.txt改为 .pth
现在我再次查看sys.path得到如下结果:
>>> import sys
>>> sys.path
'''
['',
'D:\\ProgramData\\Anaconda3\\envs\\pytorch1.2.0\\python36.zip',
'D:\\ProgramData\\Anaconda3\\envs\\pytorch1.2.0\\DLLs',
'D:\\ProgramData\\Anaconda3\\envs\\pytorch1.2.0\\lib',
'D:\\ProgramData\\Anaconda3\\envs\\pytorch1.2.0',
'C:\\Users\\Administrator\\AppData\\Roaming\\Python\\Python36\\site-packages',
'F:\\pytorch', # 这就是新添加进来的路径,而且他在第三方库之前哦
'D:\\ProgramData\\Anaconda3\\envs\\pytorch1.2.0\\lib\\site-packages'
]
'''
1.2 Linux平台之下
同样的操作,先查看sys.path所返回的路径有哪一些
>>> import sys
>>> sys.path
'''
['', # 当前目录
'/usr/local/python3/lib/python36.zip', # python标准库目录
'/usr/local/python3/lib/python3.6',
'/usr/local/python3/lib/python3.6/lib-dynload',
'/usr/local/python3/lib/python3.6/site-packages' # 第三方库所在的目录
]
'''
另外我们看一下使用site模块的情况:
import site
site.getsitepackages()
'''
['/usr/local/python3/lib/python3.6/site-packages']
'''
我们发现这虽然和window上有一些区别所在,其实原理都是一样的,这里就不再重复试验了。
1.3 在代码中手动添加搜索路径到sys.path所返回的列表中
既然前面说过sys.path返回的是一个列表,而且这个列表是动态执行的时候确定的,所以我们可以在编写代码的时候在代码最前面添加某一些需要的搜索路径到sys.path里面如下:
import sys
sys.path.append("F:/my_own_path")
但是我们一般不太推荐这样做!!!
总结:
python搜索模块的顺序为如下:
内建模块 >
程序的根目录(即当前运行python文件的目录)>
PYTHONPATH环境变量设置的目录>
标准库的目录>
任何能够找到的*.pth文件的内容>
第三方扩展的site-package目录