《老鸟python 系列》视频上线了,全网稀缺资源,涵盖python人工智能教程,爬虫教程,web教程,数据分析教程以及界面库和服务器教程,以及各个方向的主流实用项目,手把手带你从零开始进阶高手之路!点击 链接 查看详情




模块路径搜索

阅读:227567833    分享到

我们上一节学习如何自定义模块,无论是自定义模块还是内建模块还是第三方模块都是模块,他们的导入方法都是一样的,唯一的区别只是在于他们所在的路径不同。

模块路径搜索规则

大家注意:下面在描述中,我们为了表达方便,把被导入的包,模块,函数,类等等统称为模块, 在导入模块(自定义模块,内建模块,第三方模块具有一样的路径搜索规则)时,不管在程序中执行了多少次 import,该模块只会被导入一次。 这样可以防止程序重复导入模块,节省内存和计算资源。那么,当使用 import... 语句的时候,Python 解释器是怎样找到对应的模块呢,Python 会根据 sys.path 的设置,按顺序搜索模块,我们可以打印出 sys.path。

'''
hello.py 文件。
'''
import mytools                       # mytools 包在 sys.path 列表中的路径下
from mytools import myabs            # 先找到 mytools 包,再从 mytools 包下找到 myabs 模块
from mytools.myabs import myabsfunc  # 先找到 mytools 包,再从 mytools 包下找到 myabs 模块,再从 myabs 模块里找到 myabsfunc 函数
import sys  # 内建模块 sys,该模块在 sys.path 列表中的路径下

print(sys.path)

我们在 hello.py 文件中打印出了 sys.path 的路径,也就是说我们在该文件中引用的模块必须在这些路径下(直接或通过 from...间接找到),否则就找不到模块。 上面的三种导入方法 import mytoolsfrom mytools import myabs,from mytools.myabs import myabsfunc 对于 import 导入的模块,我们总是能直接或间接(通过 from...)找到,所以我们在 hello.py 中可以找到我们导入的模块。

但是我们在项目开发过程中有时候,我们的模块所放在的位置有时候并不在 sys.path 列表中,那我们如何导入该模块呢,比如我们不想通过 mytools 间接导入 myabs 模块,我们想直接通过 import 导入 myabs 模块,我们只需要把 myabs 模块所在目录加入到 sys.path 列表中即可。

'''
hello.py 文件。
'''
import sys
sys.path.append("E:\\python_one\\mytools")  # 添加字符串 "E:\\python_one\\mytools" 到 sys.path 中
print(sys.path)

import myabs  # 直接导入 myabs 模块
print(myabs.myabsfunc(-250))

用绝对路径的方式在项目开发过程中一般是不允许的,比如我们在本机上开发,项目完成后上传到服务器上, 项目程序所在服务器的盘符和我们本机的盘符不是一个名称(比如我们开发的时候把项目放在本机的 E 盘,而服务器上项目在 C 盘),大家可能会想,我们开放的时候保持和服务器盘符一样不就可以了吗,那如果我们的服务器是 linux 呢?linux 系统没有盘符的概念。我们使用相对路径是解决以上问题最好的方法。

'''
hello.py 文件。
'''
import sys
import os
thisfilepath = os.path.abspath(__file__)            # hello.py 文件全路径
thisfiledir = os.path.dirname(thisfilepath)         # hello.py 所在文件夹全路径
mytoolspath = os.path.join(thisfiledir, "mytools")  # mytools 文件夹全路径

sys.path.append(mytoolspath)  # 添加 mytoolspath 所在全路径到 sys.path 中
print(sys.path)

import myabs  # 直接导入 myabs 模块
print(myabs.myabsfunc(-250))

模块路径搜索注意事项

在我们导入模块的时候,有可能出现模块名字重名的情况,大家可能会想,我们约定好给模块起名字不重名不就可以了吗, 但是一个项目中的模块不可能是一个码农写的,总会有这种可能性;还有我们模块名也有可能和内建模块重名;也有 可能和第三方模块重名,这些可能性都有,所以我们要清楚当模块重名的情况下,Python 会按照 sys.path 列表的顺序查找的,当第一次查到后,就不会再继续查找该模块。假定我们创建一个模块 abs 和内建模块重名,我们本意是调用 Python 内置的 abs 函数做绝对值计算,但是 Python 根据 sys.path 列表里面的值,率先找到我们自己写的 abs 模块,就停止了搜索。

'''
hello.py 文件。
'''
import abs
print(abs(9))  # 这时候用的是我们自己模块 abs 而不是 Python 内置的 abs 函数,所以报错。

我们自定义的模块一般放在项目目录下,这是一个好的习惯;内置模块我们安装 Python 解释器的时候,Python 把它放在安装目录下了;第三方模块我们一般自动安装在 Python 安装目录下的 lib 目录下的 site-packages 目录下。

本节重要知识点

弄明白模块搜索路径的规则。

自定义模块的写法规范。

作业

我们自己写的模块如果放在解释器内建模块目录下,或者 site-packages 目录下,我们不就省了导入时需要自己定义路径的问题了吗 为什么我们不这样做。


如果以上内容对您有帮助,请老板用微信扫一下赞赏码,赞赏后加微信号 birdpython 领取免费视频。


登录后评论

user_image
钻木取水
2020年9月30日 04:30 回复

太赞了


user_image
Yungstedt
2020年2月1日 04:27 回复

能介绍下scrapy库安装吗


user_image
刘雅骏
2019年12月27日 06:14 回复

非常详细,感谢作者


user_image
1不2
2019年7月31日 03:34 回复

能介绍下scrapy库在64位Windows7下的python3中如何安装吗?


user_image
小爝
2018年12月27日 08:54 回复

博主,真体贴,困惑很久的问题,看完后,马上就明白了