复习
1.生成器中的send方法
-- 给当前停止的yield发生信息
-- 内部调用__next__()取到下一个yield的返回值
2.递归:函数的(直接,间接)自调用
-- 回溯 与 递推
-- 重点:出口 | 递归的条件
3.匿名函数
-- lambda 参数列表: (返回值, 返回值)
-- 应用场景:1.用变量接受 | 2.结合内置函数使用
-- add = lambda n1, n2: n1 + n2
4.内置函数
dic = {'Bob': 88888, 'Tom': 66666} | [('Bob', 88888), ('Tom', 66666)]
-- max(iter, key=lambda x: x) | min | map | reduce | sorted
-- bin | oct | hex
-- max min sum pow abs
-- len next iter range enumerate
今日内容 模块的概念、导入方式、模块搜索路径、链式导入&循环导入
一. 模块的概念:一系列功能的集合体
模块的存在形式:1)点py文件
2)某个文件夹(该文件夹下有一个_init_.py文件,该文件夹称为包)
3) 使用C编写并链接到python解释的内置模块
4)已被编译为共享库或DLL的C或C++扩展
为什么要有模块:因有很多相似的功能,为统一管理,方便使用,将这些功能放在一个文件中,该文件就是模块。
模块的使用:两种导入方式 ①import ②from... import...
二、模块的导入方式
2.1、 imoport 模块名
首次导入模块的三件事:(import spam)
①编译模块产生一个编译pyc文件,同时产生一个模块的名称空间
②执行模块spam.py内的代码,将执行过程中产生的变量名字存放于模块的名称空间中
③ 在当前执行文件中拿到一个名字,该名指向模块的名称空间(全局),通过名字点语法使用功能
之后的导入,直接引用第一次的导入成果,在当前执行文件中产生一个名字,直接指向第一次导入模块时在内存中产生的模块名称空间
#m1.py
a =10
b = lambda x: x *10
# run.py
import m1
print(m1.__dict__) # 模块的名称空间内容,名字与内存地址的对应关系(超大的字典)
print(m1.__dict__['b']) # <function <lambda> at 0x000001EF7C97BB70
# print(m1.b) # 简写
print(m1.__dict__['a']) # 10 格式化输出为10
print(m1.a) # 间写
2.2.1 from ... import ... as # 起别名:from 模块名 import 名字 as 别名
2.2.2 from ... imort * # 导入系统默认添加的_all_中的变量
而 _all_中的变量 默认剔除了以_开头的名字。所以from ... imort * 无法导入_开头的名字
#_all_ = ['a', 'b', 'c', '_e' ] 可以自定义,名字以字符的形式放于列表中
三、模块的搜索路径 :①内存 > ②内置((built-in)) > ③环境变量 【import sys; sys.path】
sys.path中为一个绝对路径列表,第一个路径默认为当前执行文件所在的文件夹
['D:\\day16', 'D:\\day16', 'D:\\Python36\\python36.zip', 'D:\\Python36\\DLLs', 'D:\\Python36\\lib', 'D:\\Python36', 'D:\\Python36\\lib\\site-packages', 'D:\\PyC]
若找不模块,两种解决方案:
1.可以将模块所在的文件夹添加到环境变量中,sys.path.append(r'D:\day16')
2. from **.** import * 【以当前执行文件为准,找到模块所在的文件夹,中间通过.语法一级级找到目标】
四、4.1 模块的链式导入
执行文件导入m1, m1导入m2, m2导入m3, 在整个执行过程中,
在执行文件中直接进入m1,执行m1,在m1执行过程中遇到导入m2,马上进入m2,执行m2遇到导入m3,进入m3,m3执行完毕,会回到m2中导入m3的语句,接着往下执行m2,m2执行完毕回到m1,以 此类推返回到t1
4.2 循环导入:应尽量避免,问题:想要访问的名字没有产生就被使用
解决:1)先产生名字,再导入
2)将有可能会产生循环导入的模块,延后导入:如放在一个函数内部中,紧贴着要访问的语句之上