可迭代对象
概念:更新换代,每次更新都是根据上一次的结果作为基础。
有哪些:字符串,列表,字典,元组,集合,文件对象,特殊函数(生成器)
迭代器对象
特点:
可调用__iter__和__next__内置方法
如何将可迭代对象变成迭代器对象:
可迭代对象调用__iter__方法就会变成迭代器对象
迭代器对象如果再次调用__iter__方法还是迭代器对象本身
作用:节省存储空间,类似range
迭代器取值特征:从左往右,取一个少一个
迭代器主要应用:无序容器的数据类型
异常处理
概念:代码运行中出现异常,报错,并停止代码的运行。
异常信息的组成部分:异常的定位,异常的类型,异常的提示。
常见异常的分类:
1.NameError 名字错误(变量名未定义)
2.IndexError 索引错误(超出索引值)
3.KeyError 键错误
4.ValueError 值错误
5.TypeError 类型错误(不满足某些特定类型的要求)
异常处理语法结构:
try:
可能会出错的代码
except 出错的类型1 as e:
针对出错类型的解决措施
except 出错的类型2 as e:
针对出错类型的解决措施
except 出错的类型3 as e:
针对出错类型的解决措施
except 万能异常(Exception) as e:
统一出错的解决措施
else:
可能会出错的代码没有出错 执行完毕后就会走else
finally:
无论上面怎么走 最后都要走finally
使用准则:被检测的代码越少越好,使用该功能越少越好
for循环本质
res = 可迭代对象.__iter__()
while True:
try:
print(res.__next__)
except StopIteration as e:
break
"""万能异常可以捕获常见的异常类型 但是并不是所有"""
今日学习内容
生成器对象(自定义迭代器)
生成后还是一个迭代器,可以调用
__iter__和__next__方法
def 生成器名():
被迭代的代码
yield 返回值 # 类似return,但是是作为生成器的关键词
被迭代的代码
作用:节省资源空间
转换生成器方式:调用一次,没调用前只是一个普通函数
取值:通过__next__,取一个少一个
报错:内部没有值,还重复取值操作就会报错
yield关键字特征:内部如果有多个yield关键字,执行一次__next__将会返回yield后面的值,然后将代码暂停在yield关键词处。再次执行yield时,将会基于上次位置,迭代取值出下一个元素。
自定义range方式
range就是一个数据集,所以自然也是一个可迭代对象
for i in range(100) 从0到99的数据集,顾头不顾尾
现在需要用生成器模拟range方法,需要满足range三个参数的功能
def my_range(start, end=None, step=1):
if not end: # 如果没有给end传值
end = start # end将会使用第一个位置参数
start = 0 # 将第一个参数为0
while start < end: # 如果起始数小于最大值,证明用户传了两个值
yield start # 返回起始值
start += step # 起始值每次增加间隔值
yield关键字作用
除了:
- 在函数体代码中出现 可以将函数变成生成器
- 在执行过程中 可以将后面的值返回出去 类似于return
- 还可以暂停住代码的运行
- 还可以接收外界的传值
def eat(name):
print(f'{name}在学习')
while True:
food = yield
print(f'{name}在学习{food}')
res = eat('eason')
res.send('python') # 可以给yield传值 并且自动调用一次__next__方法
生成表达式
作用:节省空间(前期代码量不大时,用处不大,适用于后期优化)
res = (i for i in 'eason') 循环将字符串转换成一种迭代器,
然后使用__next__迭代取。
面试小难题,周末花时间研究一下
# 普通的求和函数
def add(n, i):
return n + i
# 生成器对象 返回 0 1 2 3
def test():
for i in range(4):
yield i
# 将test函数变成生成器对象
g = test()
# 简单的for循环
for n in [1, 10]:
g = (add(n, i) for i in g)
"""
第一次for循环
g = (add(n, i) for i in g)
第二次for循环
g = (add(10, i) for i in (add(10, i) for i in g))
"""
res = list(g) # list底层就是for循环 相当于对g做了迭代取值操作
print(res)
#A. res=[10,11,12,13]
#B. res=[11,12,13,14]
#C. res=[20,21,22,23]
#D. res=[21,22,23,24]
"""正确答案是C 诀窍就是抓n是多少即可"""
模块
python拥有大量非常好使用的模块,非常适合Python工程师使用
类似之前使用过的一个时间模块
import time 导入时间模块,time.time 调用模块
鸡哥:作为一名python工程师CV大法都要比其他工程师练得更加炉火纯青!!!
概念:模块就好比如一个已经完善并蕴含丰富功能的函数的整合,这就是模块。
功能:数不胜数,集齐丰富,节省精力
来源:
- 内置模块,解释器自带
- 自定义模块,类似函数,自己写代码,封装成模块
- 第三方模块,网上前辈发布,下载后使用
表现形式
- 使用python代码编写的py文件
- 多个py文件组成的文件夹(包)
- 已被编译为共享库或DLL的c或C++扩展
- 使用C编写并链接到python解释器的内置模块
模块的两种导入方式
要想使用模块,必须先进行导入
第一种:import 模块名称
列入:
import 文件
print(文件.变量名)
文件.函数名()
这里面,调用变量名或者函数名前,只要加上了被调用过的模块的模块名,便是在调用模块内部的变量或者函数名。
1.执行当前模块时,会产生一个当前模块的名称空间
2.执行import句式时,会将模块内的代码导入这个模块的名称空间中
3.在当前模块的名称空间中,产生模块功能的名字,指向模块的名称空间
4.通过功能名字去调用模块名称空间中的代码。
如果不使用import,python是无法辨别你所调用的到底是什么,如果有相同的函数名,那么python会调用全局名称空间中的代码,使用模块中的功能,前缀一定要加上该模块的名称。
相同的模块只需要被导出一次,全局都可以使用。
第二种:from···import···句式
from 模块名 import 模块内的功能或函数名,变量名
与第一种不相同的地方在于,只有被import后面点出名字的功能或函数名,变量名,才可以被使用。
1.执行当前模块时,会产生一个当前模块的名称空间
2.执行import后点出的名字,将其加载到当前模块的名称空间中
3.通过调用import中存在的名字,使用其功能或代码
使用该模块调用方法,调用模块内名字时,不需要加模块前缀名,直接使用就可以。
所以就会导致名字冲突,调用该方法一定要注意名称冲突问题。
调用模块功能的补充
可以给模块功能赋予新的变量名,非常实用
import 模块名 as 变量名
之后就可以直接使用变量名去调用这个模块。
from 模块名 import 模块内名字 as 变量名
之后同样可以使用变量名去调用这个模块内的名字。
连续调用多个模块或模块内部名字
import 模块1,模块2,模块3
连续导入多个模块,模块之间建议要有较相似的功能部分,否则建议分开,代码一定要做到尽量简洁明了。
from 模块 import 模块内名字1,模块内名字2,模块内名字3
单个模块下,可自由调用内部名字
通用导入
from 模块名 impore *
*号可以将from方法中的所有函数名调出
from 模块名 import
这种也可以讲模块中的所有名字调出