异常处理与生成器对象

异常常见类型

异常类型有很多种 异常类型就是我们一段代码在运行时遇到bug终止运行.返回给我们一段报错信息,其中就有异常类型。
SyntaxError 语法错误
NameError 名字错误
IndexError 索引错误
KeyError  k键错误(字典中的k)
IndentationError 缩进错误
还有很多其他的异常类型。这里只是一小部分

异常处理语法结构

异常处理常用在我们可能会觉得出错的代码,出现异常后处理可以根据我们制定的方案执行。 异常处理的语法尽量少用,被检测的代码尽量少
需要使用关键字 
try:
    被监测的代码
except 错误类型:
	针对上诉错误类型制定的方案
相关关键字
try/except 捕捉异常处理
else: try子代码运行整常没有报错后在执行else子代码
finally 无论try子代码是否报错都要执行finally代码
还有两个万能异常
Exception/BaseException
-------------------------------------------------------------------------------------
组合使用:
try:
    name = 怎么回事   # 字符串没+引号
except NameError as e:
    print('确实是傻瓜')  # 错误处理后打印
else:
    print('就这么回事')
finally:
    print('此路是我的')  # 无论try子代码是否报错都要执行
    
try:
   	可能会出问题的代码
except NameError as e:
    出问题了怎么解决
else:
    可能会出问题的代码没出问题走我
finally:
    无论上述代码是否报错你都得走我

补充

断言 assert   就是预言的感觉, 我提前就告诉你我是啥类型,然后就执行断言下的代码,如果说错了,就报错。
name = '你猜我是啥类型'
assert isinstance(name, str)
print('就是字符串')
name.strip()
主动抛异常   根据我们给的条件 主动把错误报出
name = '我是你'                     '修改成我是你1号'
if name == '我是你':                  '不符合条件'
    raise Exception('我是你')  # 报错 
else:
    print('我不是你')                '打印'

for循环底层代码

l1 = [11, 22, 33, 44, 55, 66, 77, 88]
res = iter(l1)   # 使用iter方法成为 迭代器对象  
while True:  #循环
    try:
        print(res.__next__())  # 用next 方法取值,直到取完值报错
    except Exception as e:  # 捕捉报错并处理
        break

生成器对象

其实也是含有__iter__和__next__方法的迭代器对象
和迭代器对象的区别
迭代器对象是解释器自动提供的。(之前说的迭代器对象都有哪些?字符串,列表,字典,元组,集合,文件对象)
生成器对象是程序员写出来的。(代码+关键字)
特征:
函数体代码内含有关键字yield
函数名加括号并不会执行函数体代码而产生一个生成器对象
生成器对象执行双下__next__才会走函数体代码并且遇到yield就暂停,下一次循环接着上次yleld后。
功能:
停顿代码,返回数据值,接收外部数据

生成器语法

函数体代码中填写 yield关键字
------------------------------------------------------------------------------------
def foo():
    yield '第一次'  # yield 具有返回值的功能,有点像return
    """当函数体代码遇到yield关键字时第一次调用并不会执行函数体代码,把函数运行状态停留在第一次遇到yield的地方,下次从第一次往下执行"""
    yield '第二次'
    yield '第三次'
print(foo)  # <function foo at 0x00000261B5BF7A60> 一串内存地址
res = foo()  #  res接收foo返回值
print(res)  # <generator object foo at 0x00000261B562BB30> 一串内存地址
print(next(res))  第一次使用next 收到返回值 第一次 遇到yield不会往下继续执行
print(next(res))  第二次 使用next 从第一次遇到yield 往下执行
print(next(res))  第三次 使用next 从第二次遇到yield 往下执行

也可以使用for循环来取值,其本质也是next 方法取值,只不过取完值报错被for循环自动捕捉处理结束循环。
for i in res:
    print(i)
""" 第一次  第二次  第三次 """
------------------------------------------------------------------------------------
def foo():  # 1 定义函数
    print('第一次上课') # 4打印
    yield '真爽' # 5 暂停代码 返回真爽
    print('第二次上课') # 7 打印
    yield '懵逼了'  # 8 暂停代码 返回 懵逼了
    print('第三次上课')  # 10 打印
    yield '慌了'  # 11 暂停 返回慌了
res = foo()  # 2 res 接收foo返回值
for i in res:  # 3 开始循环
    print(i)  # 6 打印真爽  # 9 打印懵逼了   # 12 打印 慌了
结果:
第一次上课
真爽
第二次上课
懵逼了
第三次上课
慌了
"""可以看到每次循环到一个yield 都会返回该yield的返回值,然后再接着下一个yield 循环,当最后一个yield走完 接着开始下一次循环,没有获取到数据自动报错 for循环本质 捕捉到报错自动结束循环"""
------------------------------------------------------------------------------------
还可以接收外部的返回值
def eat(name):
    print(f'{name}上机')
    while True:
        something = yield
        print(f'{name}天生就是{something}')
res = eat('伞兵')
res.__next__()
res.send('被包围的')
send 可以给yield 前面的变量名传值,在自动调用__next__
结果:
伞兵上机
伞兵天生就是被包围的

生成器写range方法

def my_range(start, end = None, step=1):  # start 代表开始位, end 结束位, step步长 
	if not end:  # 判断 end是否没有值
        end = start  # end也绑定start的值 用在单个数值方法
        start = 0  # start = 0   在把start数值改成0
   while start < end:  # 循环判断 start 数值是否比 end 绑定数值小
    	yield start  # 停下循环  返回start值 给i 打印出来
       start += step  # 第二次for循环开始地方,第一次返回的数值加上我们设定的步长。接收whlie循环
for i in my_range(10):  
	print(i)

生成器表达式

就是我们上面写的生成器的简化写法
res = (返回值 for i in 可迭代对象)
特点:
1.简化代码。 2. 节省空间
eg: 
1. 展示
res = (i for i in '这里是个生成器表达式')
print(res)
print(next(res)) # 这
2. 展示
res = (i+1 for i in range(5))
print(next(res))  # 1  每次使用next方法只能取一个值

生成器面试题

def add(n,i):
    return n + i
def test():
    for i in range(4):
        yield i
# 把test函数变成生成器对象
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
posted @ 2022-10-17 20:29  李阿鸡  阅读(17)  评论(0编辑  收藏  举报
Title