异常捕获和生成器

目录

  • 异常捕获
    1.什么是异常
    2.异常的结构
    3.异常的常见类型
    4.异常的分类
    5.处理异常捕获的关键字及作用

  • 生成器
    1.生成器对象的本质
    2.生成器对象的目的
    3.生成器对象的实现
    4.课题小练习
    5.yield的其他用法
    6.生成器表达式

异常捕获

  • 什么是异常
    异常就是在程序运行阶段遇到逻辑或语法错误而导致程序终止。

  • 异常的结构
    1.关键字 line 所在行
    精准提示哪行代码出现问题
    2.最后一行冒号左侧
    错误的类型
    3.最后一行冒号右侧
    错误的具体原因(也是改BUG的关键)

  • 异常的常见类型
    NameError
    IndexError
    KeyError
    SyntaxError
    TypeError

  • 异常的分类

  1. 语法错误

    语法错误就是在程序端中只有输入或输出的错误

  2. 逻辑错误

    逻辑错误就是在程序中所体现的逻辑层面的错误

  • 处理异常捕获的关键字及作用

    关键字 关键字说明
    try/excrpt 捕获异常并处理
    pass 忽略异常
    as 定义到异常的实例
    Exception/BaseException 包容所有错误类型,不会出现类型不对应而产生的程序错误
    else 如果try中的语句没有引发异常,则执行else中的语句
    finally 无论是否出现异常,都执行的代码(一般放在最后)
    assert 断言,用assert isinstance()断言数据属于什么类型,不对报错,反之正常运行
    raise 抛出/引发异常
  1. 捕获异常的基本语法
try:
    可能会出错的代码(被try监控)
    except 错误类型1 as e:  # e就是具体错误的原因
        对应错误类型1的解决措施
    except 错误类型2 as e:  # e就是具体错误的原因
        对应错误类型2的解决措施
    except 错误类型3 as e:  # e就是具体错误的原因
        对应错误类型3的解决措施
    except 错误类型4 as e:  # e就是具体错误的原因
        对应错误类型4的解决措施

使用try 方法 来将逻辑错误跳过使程序正常运行,as的作用就是承接错误的原因,如若except后面的错误类型与其不对应,那么程序也会报错。

  1. 捕获异常的万能捕获方法
try:
    错误类型
except Exception as e:  # 万能异常方式1
    print(e)
except BaseException as e:  # 万能异常方式2
    print(e)

使用Exception/BaseException 可以包容所有错误类型,不会出现类型不对应而产生的程序错误

  1. 异常中的else和finally
try:
    name
except Exception as e:
    print('你出错了 你个小垃圾')
else:
    print('try监测的代码没有出错的情况下正常运行结束 则会执行else子代码')
finally:
    print('try监测的代码无论有没有出错 最后都会执行finally子代码')

使用else时,只有上述代码没有出错,正常运行结束后才能运行else后面的子代码。与while 、for、if 用法一致。
使用finally时,无论上述代码有没有出错,都能运行其后面的子代码。

  1. 异常中的断言
name = 'jason'  # 通过一系列的手段获取来的数据
assert isinstance(name, list)  # 断言数据属于什么类型 如果不对则直接报错 对则正常执行下面的代码
   print('针对name数据使用列表相关的操作')

断言数据属于什么类型 如果不对则直接报错 对则正常执行下面的代码

  1. 异常中的主动抛出/引发异常
name = input('username>>>:').strip()
if name == 'jason':
    # raise NameError('jason来了 快跑!!!')
     raise Exception('反正就是不能过')
else:
	print('不是jason 那没事了')

每次执行 raise 语句,都只能引发一次执行的异常。此次异常是主动定义的。

生成器

  • 生成器对象的本质
    生成器就是自己定义出来的,其本质就是迭代器对象
    使用方法__ iter __ 和 __ next __

  • 生成器对象的目的
    目的就是为了优化代码
    生成器可以节省数据类型的内存占用空间,是一种不依赖索引取值的通用方式

  • 生成器对象的代码实现

	 # def index():
    #     print('我是谁呀 嘿嘿嘿~')
    #     yield 111, 222, 333
    #     print('你追我 如果你追到我 我就... 嘿嘿嘿~')
    #     yield 222
    #     print('实在跑不动了 嘿嘿嘿~')
    #     yield 333
    """
    当函数体代码中有yield关键字
    那么函数名第一次加括号调用不会执行函数体代码
    而是由普通的函数变成了迭代器对象(生成器)  返回值
    """
    # print(index)  # <function index at 0x000001F499F7A5E0>
    # res = index()
    # print(res)  # <generator object index at 0x0000021E18BACA50>
    # res.__next__()
    # res.__next__()
    # res.__next__()
    """
    yield可以在函数体代码中出现多次
    每次调用__next__方法都会从上往下执行直到遇到yield代码停留在此处
    """
    # print(res.__next__())
    # print(res.__next__())
    # print(res.__next__())
    # print(res.__next__())
    """
    yield后面如果有数据值 则会像return一样返回出去
    如果有多个数据值逗号隔开 那么也会自动组织成元组返回
    """

当函数代码中有yield关键字时,函数名第一次加括号调用不会执行函数体代码,而是变成了生成器返回值

定义后方可使用。

yield 在函数体代码中可多次使用,每次调用__ next __方法都会从上往下直到遇见yield代码停留在此处

如果 yield后面有数值,则会像return一样返回出去,若有多个数值,则自动组织成元组的形式。

当调用的次数多于yield时,则会出现报错

  • 课题小练习
# 编写生成器 实现range方法的功能
def my_range(start_num, end_num=None, step=1):  # my_range(1,10,3)
    if step < 1:
        step = 1
    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, 100, 2):
#     print(i)
# for i in my_range(1, 5):
#     print(i)
# for i in my_range(10):
#     print(i)
for i in my_range(1, 100, -2):
    print(i)
  • yield的其他用法
def index(name,food=None):
    print(f'{name}准备干午饭!!!')
    while True:
        food = yield
        print(f'{name}正在吃{food}')
res = index('jason')
res.__next__()
res.send('生蚝')  # 传值并自动调用__next__方法
res.send('韭菜')  # 传值并自动调用__next__方法
res.send('腰子')  # 传值并自动调用__next__方法

针对表达式形式的yield,生成器对象必须事先被初始化一次,让函数挂起在food=yield的位置,等待调用res.send()方法为函数体传值

表达式形式的yield也可以用于返回多次值,即 变量名=yield 值 的形式

  • 生成器表达式
    创建一个生成器对象有两种方式,一种是调用带yield关键字的函数,另一种就是生成器表达式,与列表生成式的语法格式相同,只需要将[]换成(),生成器表达式返回的是一个生成器对象即:
l1= [x*x for x in range(3)]
[0, 1, 4]
l1 =(x*x for x in range(3))
print(l1)
posted @ 2022-07-12 16:14  Nirvana*  阅读(35)  评论(0)    收藏  举报