- Day22异常捕获,生成器对象
- 1、异常捕获
- 1.1、异常的结构
- 1.2、异常类型
- 1.3、异常分类
- 1.4、异常捕获实操
- 1.5、异常捕获 其他操作补充
- 1.6、for循环的本质完善
- 2、生成器对象(自定义迭代器对象)
- 2.1、**yield** 关键字
- 2.2、实现rang函数功能
- 2.3、yield其他用法
- 2.4、生成器表达式
1.2、异常类型1.1、异常的结构
- 程序在执行过程中如果出现了异常会导致整个程序结束,异常就是程序员口中的‘bug
Traceback (most recent call last): File "D:/pythonProjectDay21/Day21/a.py", line 1, inname NameError: name 'name' is not defined
- 关键字line表示出错的是哪一行,可以通过点击路径直接跳到该行
- 最后一行冒号的左侧表示错误类型。
- 冒号右侧表示错误的具体原因(这个线索是改bug的关键)
1.3、异常分类
- NameError
- 名字错误
- IndexError
- 索引错误
- keyError
- 键错误
- SyntaxError
- 语法错误(无法捕获)
- TypeError
- 类型错误
1.4、异常捕获实操
- 语法错误 (SyntaxError)
- 是不允许出现的,一旦出现要立即修改
- 逻辑错误
- 允许出现,出错之后修改即可
代码写完自己先跑一遍 没问题了再提交
1.5、异常捕获 其他操作补充
- 当代码不确定是否会报错的情况下 要懂得自己处理异常
- 编写网络爬虫访问网址数据并处,有可能出现断网,没有出现对应的数据,报错
异常捕获的使用相当于是提前预测可能出现的问题,并提前给出处理措施
异常捕获代码流程
try: 可能还会出错误的代码 except 错误类型 as e: # e 就是具体错误的原因 对应错误类型1的解决措施 except 错误类型 as e: 对应错误类型2的解决措施 except 错误类型 as e: 对应错误类型3的解决措施
- 万能异常处理方式
try: name index[0] except Exception as e: # 万能异常关键字 Exception print(e) print('你好') except BassExcption as e: # 方式二 print(e)
1.6、for循环的本质完善
- 异常捕获中,else与fimally
try: name=1 except NameError as e: print(e) print('被监代码异常执行') else: print('当被检测的代码没有异常,将会执行此代码') finally: print('无论被监测的代码是否异常,我都执行')
- 断言 assert
- 关键字 assert 判断右边为True时 正常执行,为False时报错
name='kk' assert isinstance(name,str) # 当断言右边数据类型正确时 继续执行之后代码,反之则报错 print('猜对了')
- 主动异常 raise
name=input('username>>').strip() if name=='kk': raise Exception ('反正就是不能过') # if判断成立 直接报错 else: print('不是kk 那没事了')异常捕获尽量少用,try捕获的代码能少则少
list=[1,5,2,66,41,22]
res=list.__iter__()
while True:
try:
res.__next__()
except Exception as e:
break
2、生成器对象(自定义迭代器对象)
2.1、yield 关键字2.2、实现rang函数功能
当函数中有yield关键字时,函数调用不会执行函数体代码,而是由普通函数变为迭代器对象(生成器)
yield可以在函数中出现多次,每次在调用双下next方法时都会从上往下执行直到遇到yield代码停留在此处
yield后面有数据值时则会像return一样返回出去,如果有多个数据值,那么也会自动组成元组返回
def my_range(start,end=None,step=1): # 定义函数 设置三个参数表
if not end: # 当 not end为True时 也就是end为0时或end不传值时
end=start # 将传入的唯一值给到 结束值
start=0 # 初始值默认为 0
while start
2.3、yield其他用法
2.4、生成器表达式
- yield 还可以接收外界的值
def index(name): print(f'{name}干饭时间到') while True: food=yield print(f'{name}吃的{food}') res=index('kk') # 调用函数 变成生成器对象 res.__next__() # 迭代取值 运行到yield停止 返回None res.send('阿巴') # 利用send将值传入 并调用__next__ 停止到下一次yield res.send('阿巴巴') # 利用send将值传入 并调用__next__ 停止到下一次yield
- 元组没有生成式,将它 按生成式写 就会变成生成器表达式
t1=(i for i in range(10) if i>3) print(t1) >>>at 0x000001DC06B98548>
- 特殊笔试题
def add(n, i): # 普通函数 返回两个数的和 求和函数 return n + i def test(): # 生成器 for i in range(4): yield i g = test() # 激活生成器 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) 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 理解: for循环没有结束,不会执行list(g) list(g) 没有执行 那么g = (add(n, i) for i in g) 就还只是一个生成式 因为 for循环 循环取值 绑定到n上,,取到10时 n的值已经改绑为 10 所以就变成 g = (add(10, i) for i in (add(10, i) for i in g)) 所以i为 分别 取值为0,1,2,3 答案是 20,21,22,23



