模块的分类
Python语言中,模块分为三类。
第一类:内置模块,也叫做标准库。此类模块就是python解释器给你提供的,比如我们之前见过的time模块,os模块。标准库的模块非常多(200多个,每个模块又有很多功能),我们这几天就讲常用的十几种,后面课程中还会陆续的讲到。
第二类:第三方模块,第三方库。一些python大神写的非常好用的模块,必须通过pip install 指令安装的模块,比如BeautfulSoup, Django,等等。大概有6000多个。
第三类:自定义模块。我们自己在项目中定义的一些模块。。
我们先定义一个模块,定义一个模块其实很简单就是写一个文件,里面写一些代码(变量,函数)即可。此文件的名字为meet.py,文件内容如下:
print('from the meet.py')
name = '郭宝元'
def read1():
print('meet模块:',name)
def read2():
print('meet模块')
read1()
def change():
global name
name = "宝浪"
-
模块的优点
#1:避免写重复代码 #2:可以多次利用 #3:拿来主义
-
模块导入及模块导入时发生的事情
import #导入(拿工具箱) #模块导入时,发生的事情: #1:当前的名称空间中开辟一个新的空间(模块) #2:将模块中所有的代码执行 #3:通过模块名,进行函数查找(工具) ------------------------------------ import time print(time.time()) ------------------------------------ #错误实例 import time.py print(time.py.time()) ------------------------------------
-
使用别名可以使模块名变短
import time as t print(t.time()) ------------------------------------- #使用别名也可以做一些模块的兼容性 # 做一兼容性 # choose = input(msg) # if choose == "1": # import meet # meet.func() # elif choose == "2": # import test # test.func() # # 做一兼容性 # choose = input(msg) # if choose == "1": # import meet as t # elif choose == "2": # import test as t # # t.func()
-
from调用方法
import和from的区别 import是直接吧工具箱拿过来 1:优点是不会和当前文件定义的变量或函数发生冲突 2:缺点是占用内存比较大 # import test # name = "宝元" # print(test.name) # print(name from 是导入模块中的一些函数或者变量,(直接拿工具) 1:优点是内存占用小 2:缺点是会和当前的文件定义的变量或者函数发生冲突 # from test import * 会出现覆盖的现象,不能解决 # name = "宝元" # from test import name # print(name) # 解决方法: # name = "宝元" # from test import name as n # print(name) # print(n)
-
__all__方法
# __all__ = ["可以被导入的函数名和变量名"]#在被导入的模块中使用
-
模块的两种用法
#1.脚本(在cmd中执行 python test.py) #2.模块(不使用或者导入)
-
main方法
# from test import * # if __name__ == '__main__': # 测试接口 # func() # 在当前模块中使用__name__ 就是 "__main__" # 当模块被导入的时候__name__就是被导入的模块名
-
导入路径
# import meet # print(meet.name) -------------------------------------------- # 使用相对路径: # from day15.t1 import meet # print(meet.name) ---------------------------------------- # 使用绝对路径: # 错误示例: # from r"D:" import meet # from ../ ========================================== # 正确的绝对路径: # from sys import path # path.insert(0,"D:\") # import meet # print(meet.name)
模块导入的顺序
一. py文件的两种功能
编写好的一个python文件可以有两种用途: 一:脚本,一个文件就是整个程序,用来被执行(比如你之前写的模拟博客园登录那个作业等) 二:模块,文件中存放着一堆功能,用来被导入使用python为我们内置了全局变量__name__, 当文件被当做脚本执行时:name 等于'main' 当文件被当做模块导入时:__name__等于模块名作用:用来控制.py文件在不同的应用场景下执行不同的逻辑(或者是在模块文件中测试代码)
if __name__ == '__main__':
print('from the meet.py')
__all__ = ['name', 'read1',]
name = 'meet'
def read1():
print('meet模块:',name)
def read2():
print('meet模块')
read1()
def change():
global name
name = '宝浪'
if __name__ == '__main__':
# 在模块文件中测试read1()函数
# 此模块被导入时 __name__ == meet 所以不执行
read1()
二. 模块的搜索路径
当你引用一个模块时,不见得每次都可以import到:
当咱们导入同一个目录下的模块的时候就能够使用import成功,不是同一个目录下的导入就会报错
上面的示例可以得知,引用模块也是按照一定规则进行引用的。
Python中引用模块是按照一定的规则以及顺序去寻找的,这个查询顺序为:先从内存中已经加载的模块进行寻找找不到再从内置模块中寻找,内置模块如果也没有,最后去sys.path中路径包含的模块中寻找。它只会按照这个顺序从这些指定的地方去寻找,如果最终都没有找到,那么就会报错。
内存中已经加载的模块->内置模块->sys.path路径中包含的模块
模块的查找顺序
- 在第一次导入某个模块时(比如meet),会先检查该模块是否已经被加载到内存中(当前执行文件的名称空间对应的内存),如果有则直接引用(ps:python解释器在启动时会自动加载一些模块到内存中,可以使用sys.modules查看)
- 如果没有,解释器则会查找同名的内置模块
- 如果还没有找到就从sys.path给出的目录列表中依次寻找meet.py文件。
需要特别注意的是:我们自定义的模块名不应该与系统内置模块重名。
#在初始化后,python程序可以修改sys.path,路径放到前面的优先于标准库被加载。
> > > import sys
> > > sys.path.append('/a/b/c/d')
> > > sys.path.insert(0,'/x/y/z') #排在前的目录,优先被搜索
> > > 注意:搜索时按照sys.path中从左到右的顺序查找,位于前的优先被查找,sys.path中还可能包含.zip归档文件和.egg文件,python会把.zip归档文件当成一个目录去处理,
#首先制作归档文件:zip module.zip foo.py bar.py
import sys
sys.path.append('module.zip')
import foo,bar
#也可以使用zip中目录结构的具体位置
sys.path.append('module.zip/lib/python')
#windows下的路径不加r开头,会语法错误
sys.path.insert(0,r'C:UsersAdministratorPycharmProjectsa')
#至于.egg文件是由setuptools创建的包,这是按照第三方python库和扩展时使用的一种常见格式,.egg文件实际上只是添加了额外元数据(如版本号,依赖项等)的.zip文件。
#需要强调的一点是:只能从.zip文件中导入.py,.pyc等文件。使用C编写的共享库和扩展块无法直接从.zip文件中加载(此时setuptools等打包系统有时能提供一种规避方法),且从.zip中加载文件不会创建.pyc或者.pyo文件,因此一定要事先创建他们,来避免加载模块是性能下降。