其他分享
首页 > 其他分享> > 7.12 异常捕获

7.12 异常捕获

作者:互联网

今日内容

异常捕获

1.如何理解异常
	程序在运行过程中如果出现了异常会导致整个程序的崩溃
	异常就是程序员口中的 bug
eg:
Traceback (most recent call last):
File "D:/Users/Lisony/day21/01 异常的结构.py", line 108, in <module>
    name
NameError: name 'name' is not defined
2.异常的结构
2.1.关键字line所在行
	能够精准的提示你在那一行出错
2.2.最后一行冒号左侧
	错误的类型提示
2.3.最后一行的右侧
	错误的具体原因 修改bug的的关键
3.异常的类型
	NameError 名字有错误
	IndexError 索引有错误
	KeyError  键有问题
	SyntaxError 语法错误
	TypeError 数据类型错误
4.异常的分类
	1.语法错误  不允许出现 一旦出现请立刻修改
	2.逻辑错误  允许出现 允许出错之后修改即可
以后在工作中 先把自己写的代码运行一遍看看 发现没有问题的话在提交

异常捕获实操演练

1.什么时候才会需要自己写代码异常处理
	当代码不确定什么时候会报错的情况下
   	  eg:编写网络爬虫访问网址数据并处理 有可能会出现断网数据没有处理不了
        
2.异常捕获的使用相当于提前预测可能会出现的问题 提前做好预防措施

3.异常捕获的代码实现
	3.1.语法结构:
        try:
            可能会出错的代码
        except 错误类型1 as e:  # e就是具体出现错误的说明
            对应出错类型的解决措施
        except 错误类型2 as e:  # 可以列举多个出现错误的情况
            对应出错类型的解决措施

	3.2.万能异常 不确定是什么数据类型可以使用
        关键字有两个:Exception BaseException 两个的作用一致
        try:
            jason
        except Exception as e:
            print(e)
        except BaseException as e:
            print(e)  # 错误说明 name 'jason' is not defined
            
4.异常捕获其他操作补充
	4.1.else与finally
        try:
            jason
        except Exception as e:
            print('出错了,小菜鸡')  # 出错的时候执行
        else:
            print('没有出错')  # 没有出错的时候执行
        finally:
            print('最终都会执行')  # 不管有没有出错最终都会执行
            
	4.2.断言
		断言(猜测)数据属于说明类型 对则正常运行下面代码 如果不对则会直接报错
        name ='jason'
        assert isinstance(name, dict)
        print('666')  # name不是字典类型直接报错

        name ='jason'
        assert isinstance(name, str)
        print('666') #  name数据值属于字符串类型执行666
        
	4.3.主动抛异常
        name = input('username>>>:').strip()
        if name == 'jason':
            raise Exception('鸡哥来了,快跑')
        else:
            print('不是鸡哥,那就没事了')
            
5.强调:
	5.1.捕获异常能尽量少用就尽量少用
	5.2.被try检测的代码能尽量少就尽量少

异常捕获练习

1.for循环的内部本质
	l1 = [11, 22, 33, 44, 55, 66]
	res = l1.__iter__()
    while True:
        try:
            print(res.__next__())
        except Exception as e:
            break
1.先看具体报错信息
2.再看具体定位信息
	由下往上查看
3.尽量将错误缩小到某个具体的变量
4.注意力就关注在出现这个变量的代码身上即可

生成器对象

1.本质其实就是迭代器对象
	只不过迭代器是解释器自带的 提供现成的给我们用
	生成器是需要我们自己定义出来的
	__iter__和__next__
    
2.学习生成器对象的目的是为了优化代码 减少内存占用
	一种不依赖于索引取值的通用方式
	可以节省数据类型的内存占用(主要)
    
3.生成器对象代码实现
    def func():
        print('猜猜我是谁')
        yield 111
        print('俺是老六')
        yield 6, 666
    # 当函数体代码有yield关键字
    # 那么函数名第一次加括号调用不会执行函数体代码
    # 而是有普通函数变成了迭代器对象(生成器)
    print(func)  # <function func at 0x000002A002A91EA0>
    res = func()
    print(res)  # <generator object func at 0x000002A002BD1C50>
    res.__next__()  # 猜猜我是谁
    res.__next__()  # 俺是老六
    res.__next__()  # 报错
yield可以在函数代码体出现多次

每次调用__next__方法都会从上往下执行直到遇到yield停留 
如果yield没有代码了就会报错
yield 后面有数据值则会像return一样返回 
    print(res.__next__())  # 打印猜猜我是谁 返回111
    print(res.__next__())  # 打印俺是老六 返回(6, 666)
    print(res.__next__())  # 报错
如果有多个数据值逗号隔开 那么也会自动组织成元组返回

yield其他用法

def func(name, food = None):
    print(f"{name}准备干饭了")
    while True:
        food = yield
        print(f"{name}正在吃{food}")  #  kk准备干饭了
res = func('kk') # 传参
res.__next__()  # 调用输出 会停留在yield
res.send('吃香吃香喝辣') # kk正在吃吃香吃香喝辣
send可以传值并自动调用__next__方法

课堂练习

编写生成器 实现range方法的功能
1.可以先以两个参数的功能编写  range(1, 5)
def my_range(start, end):
    while start < end:
        yield start
        start += 1
res = my_range(1, 5)
print(res.__next__())
for i in res:
    print(i)
for i in my_range(1, 5):
    print(i)
2.在考虑一个的情况
def my_range(start, end = None):
    if not end:
        end = start
        start = 0
    while start < end:
        yield start
        start += 1
for i in my_range(5):
    print(i)
3.考虑三个参数的情况 range(1, 5, 2)
def my_range(start, end = None, step = 1):
    if step < 1:
        step = 1
    if not end:
        end = start
        start = 0
    while start < end:
        yield start
        start += step
for i in my_range(1, 5, 2):
    print(i)

生成表达式

生成表达式就是为了更好节省内存
    l1 = [i*2 for i in range(10) if i > 3] # 列表生成式(方括号)
    print(l1)  # [8, 10, 12, 14, 16, 18]
    l1 = (i*2 for i in range(10) if i > 3) # 生成表达式(小括号)
    print(l1)  # <generator object <genexpr> at 0x0000020A28E21C50>
    print(list(l1))  # 转换列表打印 [8, 10, 12, 14, 16, 18]

面试题
    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)
    res = list(g)
    print(res)

    #A. res=[10,11,12,13]
    #B. res=[11,12,13,14]
    #C. res=[20,21,22,23]正确答案是C
    #D. res=[21,22,23,24]
ps:掌握技巧即可 无需深究 纯粹为了考试而出 没有多少实际意义 嵌套不符合编程规范

标签:__,name,7.12,res,捕获,yield,start,print,异常
来源: https://www.cnblogs.com/lisony/p/16471766.html