异常捕获
1. 异常通常被称为bug
2. 异常结构有三部分
报错定位 报错类型:报错详细信息
3. 异常可以出现逻辑错误,不能可以出现语法错误
4. 异常有很多类型:最常见的
BaseException/Exception 万能异常类型 AssertionError 断言语句失败 AttributeError 对象没有这个属性 ImportError 导入模块/对象失败 KeyError 映射中没有这个键 ...... https://juejin.cn/post/7119459769915539464
5. 异常捕获的语法结构
# 基本语法结构 # 1. 普通捕获报错 try: 待监测的代码(可能会出错的代码) except 错误类型: 针对上述错误类型的解决方案 # 2. 查看错误的信息 try: 待检测的代码(可能会出错的代码) except 错误类型 as e: # e是系统提示的错误信息 针对上述错误类型指定的方案 # 3. 针对不同的错误类型制定不同的解决方案 try: 待检测的代码(可能会出错的代码) except 错误类型1 as e: # e是系统提示的错误信息 针对上述错误1类型指定的方案 except 错误类型2 as e: # e是系统提示的错误信息 针对上述错误2类型指定的方案 except 错误类型3 as e: # e是系统提示的错误信息 针对上述错误3类型指定的方案 ......
# 万能异常捕获 try: 待检测的代码 except Exception as e: 针对各种常见的错误类型全部统一处理 # 异常捕获结合else使用 try: 待检测的代码(可能会出错的代码) except Exception as e: 针对各种常见的错误类型全部统一处理 else: try的子代码正常运行结束没有任何的报错后在执行else的子代码 # 异常捕获结合finally使用 try: 待监测的代码(可能会出错的代码) except Exception as e: 针对各种常见的错误类型全部统一处理 else: try的子代码正常运行结束没有任何的报错后 再执行else子代码 finally: 无论try的子代码是否报错 最后都要执行finally子代码
异常处理其他操作
1. 断言
name = 'tom' assert isinstance(name,list) # 断言数据属于什么类型 print('针对name数据使用列表相关操作')
2. 主动抛异常
name = input('用户名').strip() if name == 'jerry': raise Exception('不通过') else: print('通过了')
异常处理实战练习
1. 异常处理能少用就少用
2. 被try监测的代码能尽量少用就少用
3. 当代码中可能会出现一些无法控制的情况报错才应该考虑使用(断网)
# 使用while循环实现for循环的功能?
l1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] res = l1.__iter__() while True: try: print(res.__next__()) except Exception as e: break
for循环内部本质其实是while循环与异常捕获的结合
生成器对象
含义:
内置可以调出__iter__和__next__的迭代器对象。
与迭代器对象的区别:
迭代器对象是解释器自己提供的/迭代器对象是人为编写出来的
使用生成器对象的原因?
生成器对象可以取消对索引取值的依赖。
语法:
def 函数名():
print('') yield 返回值 # yield是创建生成器的关键字
# yield与return有些许相似,可以返回值
# 函数名加括号调用函数时,如果函数里有yield关键字就不会执行函数体代码
# 要调用函数需要现调用__next__才会执行函数体代码
# 每次执行完__next__代码都会停在yield位置,下次基于该位置往下寻找第二个yield
def my_iter():
print('123')
yield 111
print('456')
yield 222
res = my_iter()
r1 = res.__next__()
print(r1)
r2 = res.__next__()
print(r2)
yield关键字冷门用法:
1. 函数体代码中如果有yield关键字,第一次调用函数就将其变为了迭代器对象(生成器) 2. yield可以在函数中出现许多次 3. 每次调用__next__方法都会停留到yield前
def eat(name,food=None):
print(f'{name}要吃饭了')
while True:
food = yield
print(f'{name}正在吃{food}')
res = eat('jason')
res.next()
res.send('炸鸡')
使用生成器在自定义range功能
# 生成器 # 1.两个参数 def my_range(start_num, end_num=None, step=1): # 判断end_num是否有值 没有值说明用户只给了一个值 起始数字应该是0终止位置应该是传的值 if not end_num: end_num = start_num start_num = 0 while start_num < end_num: yield start_num start_num += step for i in my_range(1, 10): print(i) for i in my_range(10): print(i) for i in my_range(1, 10, 2): print(i)
生成器表达式
l1 = [i**2 for i in range(10) if i > 3] print(l1) # 加的中括号输出是一个列表 l1 = (i**2 for i in range(10) if i > 3) print(l1) # 加小括号输出的就是表达式,存在内存中,需要时才从内存中拿,省内存。 # 面试题 def add(n, i): # 普通函数 return n + 1 def test(): # 生成器 for i in range(4): yield i g = test() # 激活生成器 for n in [1, 10]: g = (add(n, i) for i in g) # g是生成器对象,必需要执行__next__否则不走 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]
'''不用深入研究 大致知道起始数即可''
标签:__,res,捕获,生成器,yield,print,异常,代码 From: https://www.cnblogs.com/juzijunjun/p/16799672.html