异常生成器
异常常见类型
语法错误 SyntaxError
if
name NameError
逻辑错误
l1 = [1,2,3]
l1[10] IndexError
d1 = {'age':18}
d1['name'] KeyError
异常处理语法结构
1.基本语法结构
try:
待监测代码(可能会出错的代码)
except 错误类型:
针对错误类型所作出的操作
2.查看错误信息
try:
待监测代码(可能会出错的代码)
except 错误类型 as 变量名:
print(变量名)
针对上述错误类型制定的方案
3.针对不同的错误类型制定不同的解决方案
try:
待监测代码(可能会出错的代码)
except 错误类型1 as 变量名:
print(变量名)
针对上述错误类型1制定的方案
except 错误类型2 as 变量名:
print(变量名)
针对上述错误类型2制定的方案
except 错误类型3 as 变量名:
print(变量名)
针对上述错误类型3制定的方案
4.万能异常 Exception/BaseException
try:
待监测代码(可能会出错的代码)
except Exception as 变量名:
print(变量名)
只有出错就执行的方案
5.与else连用
try:
待监测代码(可能会出错的代码)
except 错误类型1 as 变量名:
print(变量名)
针对上述错误类型1制定的方案
except 错误类型2 as 变量名:
print(变量名)
针对上述错误类型2制定的方案
except 错误类型3 as 变量名:
print(变量名)
针对上述错误类型3制定的方案
else:
没有出错执行这里的代码,否则不执行
6.与finally连用
try:
待监测代码(可能会出错的代码)
except 错误类型1 as 变量名:
print(变量名)
针对上述错误类型1制定的方案
except 错误类型2 as 变量名:
print(变量名)
针对上述错误类型2制定的方案
except 错误类型3 as 变量名:
print(变量名)
针对上述错误类型3制定的方案
else:
没有出错执行这里的代码,否则不执行
finally:
不论错误不错误,最终都要执行的代码
异常处理补充
1.断言
name = 'jason'
assert isinstance(name,int) # 不是直接异常
assert isinstance(name,int) # 是继续向下执行
print('abc,字符串')
2.主动抛出异常
name = 'jason'
if name == 'jason':
raise Exception('不行')
else:
print('正常运行')
异常处理实战应用
1.异常处理尽量能少用就少用
2.被try监测的代码能尽量少就少
3.当代码中可能会出现一些情况无法控制的是时候才应该考虑使用
eg:手机访问网络软件 断网
使用while循环+异常处理+迭代器对象 完成for循环迭代取值的功能
l1 = [1, 2, 3, 4, 5, 6]
res = l1.__iter__()
while True:
try:
print(res.__next__())
except StopIteration as e:
break
生成器对象
1.本质
还是内置有__iter__() __next__()的迭代器对象
2.区别
迭代器对象是解释器自动提供的
数据类型、文件对象 迭代器对象
生成器对象是程序员自己创建的
代码、关键字 迭代器对象(生成器)
3.创建生成器的基本语法
def 函数名():
函数体
yield # 不再是return了
def name():
print('进入函数内')
yield
'''
1.函数体代码有yield关键字,那么函数名加括号就不会立即执行,会生成一个生成器对象(迭代器对象)
'''
'''
res = name()
2.使用加括号之后的结果调用__next__才会执行函数体代码
'''
'''
res.__next__()
3.每次执行完__next__(),代码都会停在yield位置 下次基于该位置继续往下找第二个yield
'''
def name():
print('第一次')
yield 1
print('第二次')
yield 2
print('第三次')
yield 3
print('第四次')
yield 4
res.__next__()
res.__next__()
res.__next__()
res.__next__()
'''
第一次
1
第二次
(1, 2)
第三次
(1, 2, 3)
第四次
(1, 2, 3, 4)
4.yield 还类似于 return 可以返回返回值
'''
def name():
return 指定报错信息 # 遇到return会立即结束,然后报错
print('第一次')
yield 1
print('第二次')
yield 2
print('第三次')
yield 3
print('第四次')
yield 4
'''
5.遇到return立即报错
'''
手动实现range简单功能
def my_range(start,end=None,step=1):
if not end:
end = start
start = 0
while start<end:
yield start
start += step
res = my_range(10,19,2)
print(res.__next__())
print(res.__next__())
print(res.__next__())
可不可以,实现负数步长
def my_range(start, end=None, step=1):
if not end:
end = start
start = 0
dstep = abs(step)
dstart = start
while start < end:
yield end-start + dstart if step < 0 else start
start += dstep
res = my_range(9, 19, -3)
print(res.__next__())
print(res.__next__())
print(res.__next__())
print(res.__next__())
yield冷门用法
def name(name,age=10):
print(name,age)
age = yield 1
print(name,age)
yield
res = name('张')
res.send(None) # 使用send启动一定现有发送一次None
res.send('abc') # 将括号内的数据值传递给 yield前的变量名然后自动调用双下next
生成器表达式
生成器表达式,其实就是简化写的方式
t = (x+2 for x in range(10))
t 为生成器对象
'''<generator object <genexpr> at 0x0000021E045F9900>'''
for i in t:
print(i)
'''
2
3
4
5
6
7
8
9
10
11
'''
"""
面试题(有难度)
大致知道流程即可
"""
def add(n, i): # 普通函数 返回两个数的和 求和函数
return n + i
def test(): # 生成器
for i in range(4):
yield i
g = test() # 激活生成器 #<generator object test at 0x000002A042199900>#(1,2,3,4)
for n in [1, 10]:
g = (add(n, i) for i in g)
# g=(add(n, 0),add(n, 1),add(n, 2),add(n, 3)) n=1不使用,因为是生成不允许
# <generator object <genexpr> at 0x0000024D7F872580>
# g=(add(n, add(n, 0)),add(n, add(n, 1)),add(n, add(n, 2)),add(n, add(n, 3))) n=10不使用,因为是生成不允许
# <generator object <genexpr> at 0x0000024D7F872430>
"""
第一次for循环
g = (add(n, i) for i in g)
第二次for循环
g = (add(10, i) for i in (add(10, i) for i in g))
"""
print(g)
#n=10 不使用,因为是生成不允许
for i in g: # g=(add(n, add(n, 0)),add(n, add(n, i)),add(n, add(n, 2)),add(n, add(n, 3)))
# 不使用,因为是生成不允许 到这里开始使用n的数据值
print(i) #20
'''
20
21
22
23
'''
# res = list(g)
# print(res)
#c
#A. res=[10,11,12,13]
#B. res=[11,12,13,14]
#C. res=[20,21,22,23]
#D. res=[21,22,23,24]
'''不用深入研究 大致知道起始数即可'''