模块的查找顺序是:
1内存中已经加载的模块
2 内置模块
3 sys.path路径中包含的看模块(sys.path的第一个路径是当前执行文件所在的文件夹)
导入模块的指令:
相对于 函数名()调用函数体,函数调用会进入函数体,从上至下逐句解释执行函数体代码
导入模块,会进入模块文件,从上至下逐句解释执行模块文件代码
如果在模块中又遇到导入其他模块,会接着进入导入的模块,从上至下逐句解释执行文件中代码,依次类推
循环导入:
模块之间出现环状导入,如:m1.py 中导入了m2, m2.py中又导入了m1
循环导入的问题:
导入模块是要使用模块中的变量
正常逻辑都是在文件最上方先完成对模块的导入,再在下方定义自身模块变量,以及使用导入的模块中的变量
由于导入模块的特殊机制,第一次导入模块会编译执行导入的模块,也就是会进入模块逐句执行模块内容,再次导入只是使用内存中的名字
就会出现下面的情况,m2在使用m1中的变量x,但变量x却并未产生,这就出现了循环导入问题
m1.py文件 import m2 x = 10 print(m2.y) m2.py文件 import m1 y = 10 print(m2.x)
解决循环导入的问题:延后导入
1 将循环导入对应包要使用的变量提前定义,在导入响应的包
2 将导包的路径放到函数体中,保证存放导包逻辑的函数调用在要使用的变量定义之后
重点:
问题:from导包极容易出现循环导入问题(from 导入后马上回使用名字)
解决:建议from导入方式改用import导入方式
包:
包通过文件夹来管理一系列功能相近的模块
包:一系列模块的集合体
重点:包中一定有一个专门用来管理包中所有模块的文件
包名:存放一系列模块的文件夹的名字
包就是管理功能相近的一系列模块的文件夹
该文件夹包含一个特殊文件_init_.py
文件夹名就是包名,产生的包名就是指向包对的名称空间(_init_.py的全局名称空间)
导包完成的三件事:(!!!在导入时带点的,点左边必须是都是包)
1 编译包中的_init_.py文件,会在包中_pycache_创建对象的pyc文件
2 产生_init_.py文件的全局名称空间,用来存放_init_出现的名字
3 产生包名指向_init_.py文件的全局名称空间 | 指定变量名执行包中指定名字
包中使用import导入:绝对导入
在包的_init_文件中
import 模块名 #问题: 所属包不在环境变量,报错
import 包名.模块名 # 问题:包所属文件夹不在文件变量,报错
import 包名.文件名 as 别名 #在外界:包名.模块名 | 包名.别名 都可以访问
import 包名.模块名.名字 #问题: 导包语句 .语法左侧 必须全都是包(文件夹)
外界
import 包名
包名.名字 #访问的是 _init_中的名字
包名.模块 #访问的模块这个地址
包名.模块.名字 # 访问的模块中的名字
import 包名.模块
包名.模块 #访问的模块这个地址
包名.模块.名字 #访问的模块中的名字
from 包名 import 模块
模块 #访问的模块这个地址
模块.名字 #访问的模块中的名字
from 包名.模块 import 名字
名字 #访问的模块中的名字
包中使用form导入:相对导入
没有子包
pk包
_init_.py
名字 a=10
pkm.py
名字 b=20
在外界
import pk
pk.a 访问a
pk.b 访问b
init管理文件
a不需要操作
from .pkm import b
有子包
pk包
_init _.py
sub子包
_init_.py
名字x=10
subm..py
名字 y=10
在外界
import pk
pk.x 访问x
pk.y 访问y
在pk的_init_管理文件
from.sub import x
from .sub.subm import y
pk包
_init_.py
sub子包
_init_.py
名字x=10
subm.py
名字 y=10
在外界
import pk
pk.sub.x访问x
pk.sub.y 访问y
在pk的init 管理文件:要产生sub名字
from . import sub =>pk.sub
在sub的init管理文件:要产生x,y名字
x不需要操作 =》pk.sub.x
from .subm import y =>pk.sub.y
注:有相对导入 .语法 的文件都不能自执行
相对导入时存在于包内的语法
. 代表当前文件夹
. . 代表上一级文件夹