异常捕获、yield其他用法、生成器对象

异常捕获

1.如和理解异常

程序在运行的时候出现了异常导致整个程序结束,也称之为‘bug’

2.异常的结构

image-20220712153620497

如何理解错误提示

关键字line所在行:精准提示哪一行的代码出错

最后一行冒号左侧:错误的类型

最后一行冒号右侧:错误的具体原因(改错误的关键)

3.异常的类型

NameError:名字有错误
IndexError:索引有错误
KeyError:键有错误
SyntaxError:语法错误
TypeError:类型错误

4.异常的分类

1.语法错误

不允许出现的 一旦出现请立刻修改!!!

2.逻辑错误

允许出现的 允许出错之后修改即可!!!

异常捕获实参演练

1.什么时候会需要自己写代码处理异常

当代码不确定什么时候会报错的情况下,就是自己也不知道什么时候会报错,不会确定什么时候发生,但是会有发生的概率

eg:编写网络爬虫访问网址数据并处理 

	1.向某个网页发送请求 获取该网页的数据(可能会出现错误)

	2.处理网页数据

	有可能会出现断网数据没有处理不了

2.异常捕获的使用相当于是提前预测可能会出现的问题,然后提前给予一些处理的措施

3.异常捕获的具体使用

3.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:
    name
except NameError:
    print('name没有被定义')
'''
IndexError: list index out of range
争对不同的错误类型要做出不同的区分,使用正确的错误类型关键字
'''    
try:
    l1 = [1, 2, 3, 4]
    l1[10]
except NameError:
    print('name没有被定义')
except IndexError:
    print('索引出错了')

3.2.万能异常(笼统的处理方式,在你不知道什么错误的情况下,就是统一的处理方式)

try:
    # name
    # d = {'name':'jason'}
    # d['pwd']
    123 + 'hello'
except Exception as e:  # 万能异常方式1
    print(e)
except BaseException as e:  # 万能异常方式2
    print(e)

4.异常捕获其他操作补充

4.1.else与finally

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

4.2.断言

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

4.3.主动抛出异常

name = input('username>>>:').strip()
if name == 'jason':
    # raise NameError('jason来了 快跑!!!')
    raise Exception('反正就是不能过')
else:
    print('不是jason 那没事了')
'''可以用来处理一些紧急情况'''

5.强调

5.1.异常捕获能尽量少用就尽量少用,因为在检测一个语法的时候它在底层会消耗许多资源,代码跑起来就会消耗许多资源

5.2.被try监测的代码能尽量少就尽量少

异常捕获练习

1.for循环内部的本质
l1 = [11, 22, 33, 44, 55, 66, 77, 88]
# 变为迭代器对象
res = l1.__iter__()
while True:
    try:
        # 当出现异常的时候,捕获错误
        print(res.__next__())
    except Exception as e:
        break
2.实际项目练习
'''
	1.先看具体的报错信息
	2.再看具体的定位信息
		由下往上查看
	3.尽量将错误缩小到某个具体的变量
	4.注意力就关注在出现这个变量的代码身上即可
'''
user_data = {
    '1': {'name': 'jason', 'pwd': '123', 'access': ['1', '2', '3']},
    '2': {'name': 'kevin', 'pwd': '321', 'access': ['1', '2']},
    '3': {'name': 'oscar', 'pwd': '222', 'access': ['1']}
}

# 8定义全局变量
is_login = {
    'is_login': False,
    'access_list': []
}


def login_auth(func_id):
    def outer(func):
        def inner(*args, **kwargs):
            # 10 先判断用户是否为登陆状态
            if is_login.get('is_login'):
                # 11 获取当前用户执行权
                access = is_login.get('access')
                # !2 判断当前函数编号是否在用户权限内
                if func_id in access:

                    res = func(*args, **kwargs)
                    return res
                else:
                    print('你当前没有编号为%s的函数执行权' % func_id)
            else:
                # 1.获取用户编号
                user_id = input('请输入用户编号>>>').strip()
                # 2.判断用户编号是否存在
                if user_id in user_data:
                    # 3.获取用户名和密码
                    username = input('请输入用户名>>>').strip()
                    pwd = input('请输入密码>>>').strip()
                    # 4.比对信息
                    real_dict = user_data.get(user_id)
                    if username == real_dict.get('name') and pwd == real_dict.get('pwd'):
                        # 5 获取权限
                        access = real_dict.get('access')
                        # 9.数据正确的情况下,更改全局变量
                        is_login['is_login'] = True
                        is_login['access_list'] = access
                        #  6判断当前用户是否含有当前被装饰函数的执行权限,假设当前被转送给hi函数的红能变好为func_id
                        if func_id in access:
                            # 7有权限
                            res = func(*args, **kwargs)
                            return res
                        else:
                            print('你没有当前功能编号为%s的函数执行权' % func_id)

        return inner

    return outer


@login_auth('1')
def func1():
    print('from func1')


func1()

生成器对象

1.本质其实就是迭代器对象

迭代器对象是解释器提供给我们的,而生成器是我们自己定义出来的

2.作用

一种不依赖索引取值的通用方式,可以节省数据类型的内存占有空间,优化代码

3.生成器对象代码实现

def index():
    print('我是谁呀 嘿嘿嘿~')
    yield 111, 222, 333
    print('你追我 如果你追到我 我就...')
    yield 222
    print('实在跑不动了')
    yield 333
res = index()
print(res)  # <generator object index at 0x000001F0B264BA50>
# 在运行双下next的时候遇到yield会停下,下一次会从上一次停下的位置开始,遇到yield继续停下
res.__next__()  # 我是谁呀 嘿嘿嘿~
res.__next__()  # 你追我 如果你追到我 我就...
# res.__next__()  # 实在跑不动了
print(res.__next__())
# res.__next__()  # 这一次就报错
"""
当函数体代码中有yield关键字
那么函数名第一次加括号调用不会执行函数体代码
而是由普通的函数变成了迭代器对象(生成器)  返回值
"""
# 编写生成器 实现range方法的功能
# # 1.俩个参数的功能编写
def my_range(start_num, end_num):
    # 有条件
    while start_num < end_num:
        # 每一次执行到这就会返回一个数
        yield start_num
        # 每一次执行完以后都会加1
        start_num += 1
# for循环底层有异常捕获,不会报错
for i in my_range(1, 10):
    print(i)
# 2.以一个参数的功能编写
def my_range(start_num, end_num=None):
    if not end_num:
        end_num = start_num
        start_num = 0
    while start_num < end_num:
        # 每一次执行到这就会返回一个数
        yield start_num
        # 每一次执行完以后都会加1
        start_num += 1
# for循环底层有异常捕获,不会报错
for i in my_range(10):
    print(i)
# 3.考虑三个参数的情况
def my_range(start_num, end_num=None, step=1):
    if not end_num:
        end_num = start_num
        start_num = 0
    while start_num < end_num:
        # 每一次执行到这就会返回一个数
        yield start_num
        # 每一次执行完以后都会加1
        start_num += step
# for循环底层有异常捕获,不会报错
for i in my_range(10):
    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__方法
'''
send的功能:
1.给前面yield里面传值
2.会自动调用一个双下next方法
yield的功能:
不仅仅可以返回一个值,而且还可以传值
'''

生成器表达式

为了节省存储空间,在后期做代码优化的时候可以用到

l1 = (i**2 for i in range(10) if i > 3)
print(l1)
# <generator object <genexpr> at 0x0000022003D2BA50>
posted @ 2022-07-12 18:56  张张包~  阅读(52)  评论(0编辑  收藏  举报