内容概要
- 索引取值与迭代取值的差异
- 模块简介
- 导入模块的两种句式
- 导入模块的句式补充
- 循环导入问题及解决策略
- 判断文件类型
- 模块的查找顺序
- 模块的绝对导入与相对导入
- 包
索引取值与迭代取值的差异
l1 = [11, 22, 33, 44, 55]
1.索引取值
可以任意位置任意次数取值
不支持无序类型的数据取值
2.迭代取值
只能从前往后依次取值无法后退
支持所有类型的数据取值(无序有序)
ps:两者的使用需要结合实际应用场景
模块简介
1.模块的本质
内部具有一定的功能(代码)的py文件
2.python模块的历史
python刚开始的时候所有搞其他编程语言的程序员都看不起 甚至给python起了个外号>>>:调包侠(贬义词)
随着时间的发展项目的复杂度越来越高 上面那帮人也不得不用一下python 然后发现真香定律>>>:调包侠(褒义词)
3.python模块的表现形式
1.py文件(py文件也可以称之为是模块文件)
2.含有多个py文件的文件夹(按照模块功能的不同划分不同的文件夹存储)
3.已被编译为共享库或DLL的c或C++扩展(了解)
4.使用C编写并链接到python解释器的内置模块(了解)
'''
包
大白话:多个py文件的集合>>>:文件夹
专业:内部含有__init__.py文件的文件夹(python2必须要求 python3无所谓)
'''
4.模块分类
1.自定义模块
我们自己写的模块文件
2.内置模块
python解释器提供的模块
3.第三方模块
别人写的模块文件(python背后真正的大佬)
导入模块的两种句式
"""
强调:
1.一定要搞清楚谁是执行文件 谁是被导入文件
2.以后开发项目的时候py文件的名称一般是纯英文
不会含有中文甚至空格
01 作业讲解.py 不会出现
test.py views.py 出现
3.导入模块文件不需要填写后缀名
"""
1.import句式
以import a为例研究底层原理
"""
1.先产生执行文件的名称空间
2.执行被导入文件的代码 将产生的名字放入被导入文件的名称空间中
3.在执行文件的名称空间中产生一个模块的名字
4.在执行文件中使用该模块名点的方式使用模块名称空间中所有的名字
"""
2.from...import...句式(impoert后可以跟多个名字eg: from a import b,c,d )
以from a import name,func1为例研究底层原理
"""
1.先产生执行文件的名称空间
2.执行被导入文件的代码 将产生的名字放入被导入文件的名称空间中
3.在执行文件的名称空间中产生对应的名字绑定模块名称空间中对应的名字
4.在执行文件中直接使用名字就可以访问名称空间中对应的名字
"""
导入模块句式补充
1.import与from...import...两者优缺点
import句式
每次使用模块名称空间中的名字都必须使用模块名点的方式才可以用
所以不会轻易的被执行文件中的名字替换掉(如果在执行文件名称空间对名字重新赋值,也能再在模块中使用该名字)
from...import...句式
指名道姓的导入模块名称空间中需要使用的名字 不需要模块名点
但是容易跟执行文件中名字冲突(如果在执行文件名称空间对名字重新赋值,就不能再在模块中使用该名字)
2.重复导入模块
解释器只会导入一次 后续重复的导入语句并不会执行
import md 有效
import md 无效
import md 无效
3.起别名
当不同程序员开发了相同模块名的不同模块
当模块名很复杂
import wuyongerciyuan as wy
from wuyongerciyuan import zhangzehonglovezhanghong as zz
from a import name as n,func1 as f1
4.多个模块导入
import a
import wuyongerciyuan
如果模块功能相似度不高 推荐使用第一种 相似度高可以使用第二种
import a, wuyongerciyuan
5.from a import * 与 __all__
from a import * *默认是将模块名称空间中所有的名字导入
__all__ = ['名字1', '名字2'] 针对*可以限制拿的名字
循环导入问题及解决策略
import可以在任意位置使用(解决循环导入问题)
1.循环导入
两个文件之间彼此导入彼此并且相互使用各自名称空间中的名字 极容易报错
2.如何解决循环导入问题
1.确保名字在使用之前就已经准备完毕(一错再错:既然出现了循环导入,只能提前准备完毕尽量解决(还是会出现错误:后面会再多循环一次))
方式一:将导入模块的句式写在定义名字的下面
方式二:将导入模块的句式写在函数体
2.我们以后在编写代码的过程中应该尽可能避免出现循环导入
![image]()
判断文件类型
1、执行文件
2、被导入文件
所有的py文件都可以直接打印__name__对应的值
当py文件是执行文件的时候__name__对应的值是__main__
当py文件是被导入文件的时候__name__对应的值是模块名
if __name__ == '__main__':
print('哈哈哈 我是执行文件 我可以运行这里的子代码')
上述脚本可以用来区分所在py文件内python代码的执行
(用if __name__ == '__main__':隔开,上面写调用模块时要执行的代码,下面放不需要执行的代码(如测试代码))
简写模式:输入main按Tab
使用场景
1.模块开发阶段
2.项目启动文件
模块的查找顺序
1.内存
import aaa
import time
time.sleep(15)
print(aaa.name)
aaa.func1()
'''当内存读取过之后就算睡眠期间硬盘中已经删除,内存中也可以使用一次'''
2.内置
import time
print(time)
print(time.name)
"""
以后在自定义模块的时候尽量不要与内置模块名、第三方模块名冲突
"""
3.执行文件所在的sys.path(系统环境 类似于环境变量)
一定要以执行文件为准!!!(不然就算有也找不到)
如果没找到模块 解决方案:
方式一:
我们可以将模块所在的路径也添加到执行文件的sys.path中即可
import sys
print(sys.path) # 列表
sys.path.append(r'D:\pythonProject03\day17\mymd')
import ccc
print(ccc.name)
'''上述模块ccc路径添加到执行文件的sys.path之后,理论上如果想要在ccc中找执行文件或者跟执行文件的位置相同的文件应该找不到,但pycharm能找到'''
'''特别:pycharm会自动将项目目录所在路径添加到sys.path中'''
方式二:利用from...import...句式指名道姓的查找
eg:
from aaa import mm # 从aaa文件夹中导入mm模块
print (mm.name)
from aaa.bbb.ccc import mm # 通过点的方式进入下一层目录
print (mm.name)
'''依次查找完还没找到就会报错'''
绝对导入与相对导入
"""
再次强调:一定要分清楚谁是执行文件!!!
模块的导入全部以执行文件为准
"""
绝对导入 (永远按照执行文件所在路径一层层往下查找)
from mymd.aaa.bbb.ccc.ddd import name # 可以精确到(模块中的)变量名
from mymd.aaa.bbb.ccc import ddd # 也可以精确到模块名
ps:套路就是按照项目根目录一层层往下查找
相对导入
.在路径中表示当前目录
..在路径中表示上一层目录
..\..在路径中表示上上一层目录
不再依据执行文件所在的sys.path 而是以 模块自身 路径为准
from . import b()
from .. import c()
from ... import d()
相对导入只能用于 模块文件 中 不能在执行文件中使用
'''
相对导入使用频率较低 一般用绝对导入即可 结构更加清晰
'''
![image]()
![image]()
包
大白话:多个py文件的集合>>>:文件夹
专业:内部含有__init__.py文件的文件夹(python2必须要求 python3无所谓)
#1. 在python3中,即使包下没有__init__.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包报错
#2. 创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包的本质就是一种模块